# Workable Jobs Monitor & Scraper (`cliqtomedia/workable-jobs-monitor-scraper`) Actor

Scrape public jobs from Workable company career pages and jobs.workable.com search: descriptions, locations, departments and optional salary. Monitor mode returns only new, changed and removed jobs.

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

## Pricing

from $0.90 / 1,000 job rows

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

![Workable jobs to clean data: company career pages and job search, with new, changed and removed jobs](https://api.apify.com/v2/key-value-stores/W3mYszw9eA31SErHK/records/hero.png)

Workable Jobs Monitor & Scraper collects public jobs from company career pages on Workable (`apply.workable.com/<company>`) and from the Workable job search (`jobs.workable.com`). It returns one clean row per job, and on a schedule it can return only new, changed and removed jobs.

Use it to track hiring at companies you care about, to build a job feed, or to find job leads by keyword and location. The smallest run is one company name, for example `costello-medical`.

### Table of contents

- [What it does](#what-it-does)
- [Quick start](#quick-start)
- [Use cases](#use-cases)
- [Input](#input)
- [Output](#output)
- [Monitoring: only new, changed and removed jobs](#monitoring-only-new-changed-and-removed-jobs)
- [Pricing and limits](#pricing-and-limits)
- [API, export and integrations](#api-export-and-integrations)
- [Troubleshooting](#troubleshooting)
- [FAQ](#faq)
- [Related Actors](#related-actors)
- [Support](#support)

### What it does

The Actor reads two public Workable sources. No login, cookie or Workable API key is needed.

1. **Company career pages.** Add a company name or its career page URL. The Actor returns every published job of that company with title, locations, department, employment type, experience, industry, posting date, links and the full job description split into description, requirements and benefits. This uses 2 requests per company, even for companies with hundreds of jobs.
2. **Workable job search.** Add keywords and/or a location. The Actor goes through the search results page by page (20 jobs per page) and returns each job with company, location, workplace type and description.

Every run also saves a short status report: for each company and search you see `complete`, `partial`, `not_found`, `error` or `skipped`, with the reason. A company that does not exist or a blocked request never looks like a successful empty result.

#### Good fit

- Watch the career pages of competitors, clients or target accounts and get new jobs every day.
- Build a job board or a job alert from Workable companies and keywords.
- Collect hiring signals (department, location, seniority) for sales or market research.

#### Not a fit / limits

- Only public, published jobs. No applicant data, no private postings.
- Companies with their own career site and no `apply.workable.com/<company>` page are not supported.
- Salary is published by only some employers. You get it only with **Add salary and exact workplace type** on, and only for company pages. The search does not return salary.
- Workable limits how many requests one IP address can make per day. Large runs can stop early with a clear `partial` status (see [Pricing and limits](#pricing-and-limits)).
- Up to 5,000 jobs per run.

### Quick start

1. Open the **Input** tab.
2. In **Companies on Workable** (`companies`) keep the prefilled `costello-medical` or add your own company name or URL.
3. Keep the other settings as they are. By default the Actor returns all current jobs (`mode`: `all`).
4. Click **Start**.
5. Open the **Output** tab. The table shows one row per job with title, company, location and job URL.

Expected result: about 20–30 rows for `costello-medical` (the number changes when the company hires), and status `complete` in the run summary.

### Use cases

| Buyer job | Input path | Output entity | Key fields | Next step |
| --- | --- | --- | --- | --- |
| Track hiring at known companies | `companies` + `mode: changes` on a schedule | new / changed / removed job | `change_type`, `title`, `location`, `url` | Send new rows to Slack, email or a sheet |
| Find jobs by keyword and place | `searchKeywords` + `searchLocation` | job | `title`, `company_title`, `workplace_type`, `date_posted` | Job board, alert, CRM |
| Hiring signals for sales | `companies` | job | `department`, `experience`, `function`, `locations` | Lead scoring |
| Salary research (where published) | `companies` + `includeDetails: true` | job | `salary_min`, `salary_max`, `salary_currency`, `salary_period` | Spreadsheet |

### Input

#### Input fields

| Field | Plain name | Type | Required | Default / prefill | Allowed values | Effect | Example | Recommendation |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| `companies` | Companies on Workable | array of strings | one of `companies`, `searchKeywords`, `searchLocation` | prefill `["costello-medical"]` | up to 200; company name, `https://apply.workable.com/<company>/`, a job URL of that company, or `https://<company>.workable.com` | Reads each company career page | `["treatwell", "https://apply.workable.com/skroutz/"]` | Use the name from the career page URL |
| `searchKeywords` | Search keywords | array of strings | see above | empty | up to 20, each up to 100 characters | One Workable search per keyword | `["data analyst"]` | Short role names work best |
| `searchLocation` | Search location | string | see above | empty | up to 100 characters | Location for every keyword search; can be used alone | `"United Kingdom"` | Use a country or city name |
| `postedWithin` | Posted within | string | no | `any` | `any`, `24h`, `7d`, `30d` | Keeps only recent jobs (search and companies) | `"7d"` | Use `24h` or `7d` for daily alerts |
| `workplaceTypes` | Workplace type | array | no | empty (all) | `remote`, `hybrid`, `on_site` | Keeps only these workplace types | `["remote"]` | For companies, hybrid/on-site need `includeDetails` |
| `titleKeywords` | Job title must contain | array of strings | no | empty | up to 50 | Keeps jobs whose title contains any word | `["engineer"]` | Matching is "contains", not case-sensitive |
| `excludeTitleKeywords` | Job title must not contain | array of strings | no | empty | up to 50 | Drops jobs whose title contains any word | `["intern"]` | "intern" also drops "International" |
| `locationKeywords` | Location must contain | array of strings | no | empty | up to 50 | Keeps jobs with a matching location | `["germany"]` | Checks all locations of a job |
| `departmentKeywords` | Department must contain | array of strings | no | empty | up to 50 | Keeps jobs with a matching department | `["sales"]` | Many jobs have no department |
| `includeDetails` | Add salary and exact workplace type (companies) | boolean | no | `false` | `true`, `false` | +1 request per company job: adds salary and hybrid/on-site | `true` | Use for small runs only; Workable limits these requests per day |
| `mode` | Mode | string | no | `all` | `all`, `changes` | `changes` returns only new, changed and removed jobs since the last run | `"changes"` | Use `changes` on a schedule |
| `monitorStateKey` | Monitor name | string | no | built from your sources and filters | letters, digits, `-`, `_`; 1–60 | Runs with the same name share memory | `"competitors-daily"` | Set it if you plan to edit the input later |
| `includeUnchanged` | Also return unchanged jobs | boolean | no | `false` | `true`, `false` | In `changes` mode also returns unchanged jobs | `true` | Use when you want the full list plus labels |
| `maxJobsPerSource` | Max jobs per company or search | integer | no | `1000` | 1–5000 | Stops one company or search; it becomes `partial` | `200` | Lower it for quick tests |
| `maxJobsTotal` | Max jobs per run | integer | no | `5000` | 1–5000 | Stops the whole run | `500` | Split bigger work into several runs |

Empty input: the run fails at once with a clear message and makes no requests. Duplicate companies (for example a name and the same company URL) are read once. Duplicate jobs inside one search are returned once.

#### Interacting settings

| When | Input A | Input B | Effective behavior | Cost/result effect |
| --- | --- | --- | --- | --- |
| Keywords and location | `searchKeywords` | `searchLocation` | Each keyword is searched in that location | One search per keyword |
| Only a location | `searchLocation` | no keywords | One search for all jobs in that location | Big locations reach the limits fast |
| Workplace filter on companies | `workplaceTypes` | `includeDetails: false` | Only `remote` jobs are recognized; hybrid and on-site are unknown | Turn on `includeDetails` to filter hybrid/on-site |
| Limits | `maxJobsPerSource` | `maxJobsTotal` | The smaller limit wins; later sources become `skipped` | You pay only for returned rows |
| Monitoring and limits | `mode: changes` | a source is `partial` | No `removed` rows for that source in that run | Prevents false "removed" jobs |

#### Input examples

##### All jobs of two companies

```json
{
  "companies": ["costello-medical", "https://apply.workable.com/treatwell/"]
}
```

Expected behavior: 4 requests, one row per job.
Expected output: `title`, `company_title`, `locations`, `department`, `description_text`.
Limit or cost note: no salary in this mode.

##### Search with filters

```json
{
  "searchKeywords": ["software engineer"],
  "searchLocation": "United States",
  "postedWithin": "7d",
  "maxJobsPerSource": 100
}
```

Expected behavior: up to 5 search pages; the search is `partial` if more jobs exist.
Expected output: `title`, `company_title`, `location`, `workplace_type`, `url`.

##### Daily monitoring

```json
{
  "companies": ["costello-medical", "treatwell"],
  "searchKeywords": ["data analyst"],
  "searchLocation": "United Kingdom",
  "mode": "changes",
  "monitorStateKey": "uk-analysts"
}
```

Expected behavior: the first run returns all current jobs as `new`. Next runs return only `new`, `changed` and `removed` jobs.

### Output

Each Dataset row is one job (or one change in `changes` mode). Every row has all fields below. A field is `null` when Workable does not publish the value or when it does not apply to that source.

#### Output fields

| Field | Meaning | Type | Can be empty? | Example / enum | Notes |
| --- | --- | --- | --- | --- | --- |
| `id` | Stable job ID | string | no | `266B371E9C` | Company: Workable shortcode. Search: Workable job ID |
| `source_type` | Where the row comes from | string | no | `company`, `search` | |
| `source_input` | Company name or search text | string | no | `costello-medical`, `software engineer @ United States` | |
| `title` | Job title | string | no | `Accounts Assistant` | |
| `state` | Publication state | string | yes | `published` | `null` on `removed` rows |
| `language` | Job language | string | yes | `en` | Search, or companies with `includeDetails` |
| `date_posted` | Posting date (ISO 8601) | string | yes | `2026-09-23T00:00:00.000Z` | Company pages publish the date only |
| `date_updated` | Last update (ISO 8601) | string | yes | `2026-04-03T07:23:15.597Z` | Search only |
| `url` | Job page | string | no | `https://apply.workable.com/costello-medical/j/266B371E9C/` | |
| `application_url` | Apply page | string | yes | `…/j/266B371E9C/apply/` | Companies only |
| `shortcode` | Workable job shortcode | string | yes | `266B371E9C` | Companies only |
| `company_slug` | Company name in the URL | string | yes | `costello-medical` | Companies only |
| `company_id` | Workable company ID | string | yes | UUID | |
| `company_title` | Company name | string | yes | `Costello Medical` | |
| `company_website` | Company website | string | yes | URL | |
| `company_url` | Company page on Workable | string | yes | `https://apply.workable.com/costello-medical/` | |
| `company_image` | Company logo URL | string | yes | URL | |
| `location` | Main location | string | yes | `Boston, Massachusetts, United States` | |
| `location_city` | City | string | yes | `Boston` | |
| `location_subregion` | State or region | string | yes | `Massachusetts` | |
| `location_country` | Country | string | yes | `United States` | |
| `location_country_code` | Country code | string | yes | `US` | Companies only |
| `locations` | All locations | array of strings | no (can be `[]`) | `["Boston, Massachusetts, United States"]` | Search may include `TELECOMMUTE` |
| `workplace_type` | Workplace | string | yes | `remote`, `hybrid`, `on_site` | Companies without `includeDetails`: only `remote` or `null` |
| `employment_type` | Employment type | string | yes | `Full-time`, `Contract` | |
| `department` | Department | string | yes | `Operations` | |
| `experience` | Seniority | string | yes | `Entry level` | Companies only |
| `industry` | Industry | string | yes | `Pharmaceuticals` | Companies only |
| `function` | Job function | string | yes | `Finance` | Companies only |
| `education` | Education | string | yes | `Unspecified` | Companies only |
| `salary_min` | Salary from | number | yes | `33250` | Companies + `includeDetails`, when published |
| `salary_max` | Salary to | number | yes | `43450` | as above |
| `salary_currency` | Currency | string | yes | `EUR` | as above |
| `salary_period` | Salary period | string | yes | `year` | as above |
| `is_featured` | Featured in search | boolean | yes | `false` | Search only |
| `social_sharing_description` | Short summary | string | yes | text | Search only |
| `description_html` | Main description (HTML) | string | yes | HTML | |
| `description_text` | Main description (plain text) | string | yes | text | |
| `requirements` | Requirements (plain text) | string | yes | text | |
| `requirements_html` | Requirements (HTML) | string | yes | HTML | |
| `benefits` | Benefits (plain text) | string | yes | text | |
| `benefits_html` | Benefits (HTML) | string | yes | HTML | |
| `details_error` | Why salary/workplace are missing | string | yes | `DAILY_LIMIT`, `HTTP_ERROR` | Only with `includeDetails` |
| `source_query_keyword` | Search keyword | string | yes | `software engineer` | Search only |
| `source_query_location` | Search location | string | yes | `United States` | Search only |
| `change_type` | Change since last run | string | yes | `new`, `changed`, `unchanged`, `removed` | `null` in `mode: all` |
| `first_seen_at` | First time this monitor saw the job | string | yes | ISO 8601 | `changes` mode only |
| `content_hash` | Fingerprint of the job content | string | no | 64 hex characters | Used to detect changes |
| `scraped_at` | When the row was made | string | no | ISO 8601 | |

When an employer writes everything in one text, `requirements` and `benefits` stay `null` and the full text is in `description_html`.

#### Output surfaces

| Situation | Where | Shape | What to do |
| --- | --- | --- | --- |
| Normal job | Dataset (Output tab) | one row per job | Open, filter or export |
| Company has no open jobs | Dataset + `OUTPUT` | no rows; source `complete`, `jobs_found: 0` | Nothing to fix |
| Company name does not exist | `OUTPUT` | source `not_found` | Check the company name |
| Limit reached or Workable daily limit | Dataset + `OUTPUT` | rows found so far; source `partial` with reason | Raise the limit or run the rest later |
| Every source failed | run status `Failed` + `OUTPUT` | `status: failed` with reason | Read the message and retry later |

The key-value store record `OUTPUT` has the run result and one entry per company/search: `status`, `reason`, `jobs_found`, `jobs_matched`, `jobs_emitted`, `new`, `changed`, `removed`. `RUN_SUMMARY` adds timing, request counts, filters and the monitor name.

#### Output example

Input: `{"companies": ["costello-medical"]}`. One real row, long texts shortened:

```json
{
  "id": "266B371E9C",
  "source_type": "company",
  "source_input": "costello-medical",
  "title": "Accounts Assistant",
  "state": "published",
  "date_posted": "2026-09-23T00:00:00.000Z",
  "url": "https://apply.workable.com/costello-medical/j/266B371E9C/",
  "application_url": "https://apply.workable.com/costello-medical/j/266B371E9C/apply/",
  "company_title": "Costello Medical",
  "company_url": "https://apply.workable.com/costello-medical/",
  "location": "Boston, Massachusetts, United States",
  "location_country_code": "US",
  "locations": ["Boston, Massachusetts, United States"],
  "workplace_type": null,
  "employment_type": "Full-time",
  "department": "Operations",
  "experience": "Entry level",
  "industry": "Pharmaceuticals",
  "function": "Finance",
  "salary_min": null,
  "description_text": "Role Summary\n\n- Responsibilities: By stepping into the Accounts Assistant role at Costello Medical, you will support …",
  "requirements": "About You\n\nWe are looking for an enthusiastic and ambitious individual …",
  "benefits": "About Costello Medical\n\nCostello Medical is a rapidly growing global healthcare agency …",
  "change_type": null,
  "content_hash": "…"
}
```

### Monitoring: only new, changed and removed jobs

Set `mode` to `changes` and run the same input on a schedule.

- **First run:** there is no memory yet, so every current job is returned as `new`.
- **Next runs:** you get only `new` jobs, `changed` jobs (title, locations, workplace, department, salary, description or apply link changed) and `removed` jobs (no longer published). If nothing changed, the Dataset is empty and `OUTPUT` shows `0 new, 0 changed, 0 removed`.
- **Removed jobs** are reported only when the company or search was read completely in that run. If a source is `partial` or failed, its old jobs are kept and checked again next time, so a temporary problem does not create false `removed` rows.
- **Memory** is kept in your account in the key-value store `workable-jobs-monitor-state`, one record per monitor name. If you change companies, searches or filters, a new monitor name is made automatically and the first run is a new baseline. Set `monitorStateKey` to keep the same memory.
- For searches with `postedWithin`, jobs that only got older than the window are not reported as removed.

### Pricing and limits

#### Pricing unit

This Actor uses pay per event:

- **$0.002 per run start** (Apify run start event, one per GB of memory; the default 512 MB counts as one).
- **$0.0009 per job row** saved to the Dataset. In `changes` mode you pay only for returned rows (`new`, `changed`, `removed`, and `unchanged` only if you ask for them).

The `OUTPUT` and `RUN_SUMMARY` records are free. Companies or searches that return nothing do not add row charges. Use **Max charge per run** in the run options to cap the cost; the Actor stops saving rows when the cap is reached and marks the run `partial`.

#### Cost examples

| Scenario | Input scope | Rows | Price |
| --- | --- | ---: | ---: |
| One small company | `costello-medical` | ~26 | ~$0.025 |
| 100 jobs | search with `maxJobsPerSource: 100` | 100 | $0.092 |
| 1,000 jobs | several companies | 1,000 | $0.902 |
| Run maximum | `maxJobsTotal: 5000` | 5,000 | $4.502 |
| Daily monitor, no changes | `mode: changes` | 0 | $0.002 |

#### Limits

- **5,000 jobs per run** (`maxJobsTotal`). A tested run returned 5,000 rows in about 6.5 minutes.
- **Workable daily request limits.** Workable limits how many search pages and job-detail requests one IP address can make per day. When the limit is reached, Workable asks to wait about 24 hours. The Actor then stops asking for that kind of data, saves everything found so far and marks the source `partial` with the reason. In a test run this happened after about 400 search pages (about 8,000 search jobs). Company pages without `includeDetails` use only 2 requests per company and are rarely affected.
- Default memory 512 MB and timeout 30 minutes are enough for 5,000 rows.

### API, export and integrations

- **Export:** in the Output tab use **Export** to download JSON, CSV, Excel, XML or HTML.
- **API:** start the Actor with the [Apify API](https://docs.apify.com/api/v2) and read the Dataset items endpoint. Read `OUTPUT` from the run's default key-value store to see the status of each company and search.
- **Scheduling:** create an [Apify schedule](https://docs.apify.com/platform/schedules) with `mode: changes` to get only new, changed and removed jobs.
- **Webhooks / no-code:** use [Apify integrations](https://docs.apify.com/platform/integrations) (Make, Zapier, Slack, Google Sheets, webhooks) to send new rows when a run finishes.
- **AI agents / MCP:** the Actor can be called from the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp) like any other Actor.

### Troubleshooting

#### A company returns `not_found`

Symptom: `OUTPUT` shows `not_found` for a company.
Likely reason: the name is not a Workable company name, or the company left Workable.
Check: open `https://apply.workable.com/<name>/` in a browser.
Action: copy the name exactly from the career page URL.

#### A source is `partial` with "daily request limit"

Symptom: fewer jobs than expected; the reason mentions Workable's daily limit.
Likely reason: Workable limited requests from the IP address used by the run.
Check: the rows already saved are valid and paid only once.
Action: run the remaining companies or searches later or in smaller runs; turn off `includeDetails` if you do not need salary.

#### No hybrid or on-site jobs with the workplace filter

Symptom: `workplaceTypes: ["hybrid"]` returns no company jobs.
Likely reason: without `includeDetails`, company pages show only whether a job is remote.
Action: turn on `includeDetails` for small runs, or leave `workplaceTypes` empty and check `workplace_type` later.

#### The run failed at once

Symptom: run status `Failed` with "INVALID_INPUT".
Likely reason: no company and no search, or a URL that is not a Workable company page.
Action: read the message; it lists each wrong value.

### FAQ

#### Do I need a Workable account or API key?

No. The Actor reads public career pages and the public job search only.

#### Why is salary empty?

Salary needs `includeDetails` and is filled only when the employer publishes it on the company page. The search never returns salary.

#### How fresh is the data?

Each run reads Workable at run time. `scraped_at` shows when each row was made.

#### Can I get all jobs from Workable?

No. One run returns up to 5,000 jobs, and Workable limits requests per day. Use companies, keywords, locations and `postedWithin` to focus on the jobs you need.

#### Are duplicates removed?

Yes. A company added twice is read once, and a job that appears on two search pages is returned once. The same job found by two different keywords appears once per search.

#### What does `partial` mean?

Some jobs of that company or search are missing because a limit was reached or Workable refused more requests. The reason is in `OUTPUT`. Rows that were saved are correct.

### Related Actors

- [Greenhouse Jobs Scraper & Monitor](https://apify.com/cliqtomedia/greenhouse-jobs-monitor-scraper) — the same job for companies that hire on Greenhouse.
- [Lever Job Scraper](https://apify.com/cliqtomedia/lever-jobs-scraper) — jobs from Lever career pages.
- [Ashby Jobs Scraper](https://apify.com/cliqtomedia/ashby-jobs-scraper) — jobs from Ashby career pages.
- [Wellfound Jobs Scraper](https://apify.com/cliqtomedia/wellfound-jobs-scraper) — startup jobs from Wellfound.

### Support

For a bug, question or feature request, open the **Issues** tab of this Actor. Include the run ID, the input mode and the error text from `OUTPUT`. Never send API tokens or private data.

This Actor is not affiliated with or endorsed by Workable.

# Actor input Schema

## `companies` (type: `array`):

Company career pages on Workable. Use the account name (costello-medical) or a URL like https://apply.workable.com/costello-medical/. A job URL from the same company also works. Up to 200 companies.

## `searchKeywords` (type: `array`):

Search all Workable jobs on jobs.workable.com. Each keyword is a separate search, for example "software engineer". Up to 20 keywords.

## `searchLocation` (type: `string`):

Location for every keyword search, for example "United States", "London" or "Germany". You can also use it alone, without keywords.

## `postedWithin` (type: `string`):

Only jobs posted in this period. Works for both search and companies.

## `workplaceTypes` (type: `array`):

Keep only remote, hybrid or on-site jobs. Leave empty for all. For companies, hybrid and on-site are known only when "Add salary and exact workplace type" is on; otherwise only remote jobs are recognized.

## `titleKeywords` (type: `array`):

Keep a job if its title contains at least one of these words (not case-sensitive).

## `excludeTitleKeywords` (type: `array`):

Drop a job if its title contains any of these words, for example "intern".

## `locationKeywords` (type: `array`):

Keep a job if any of its locations contains one of these words, for example "Germany" or "London".

## `departmentKeywords` (type: `array`):

Keep a job if its department contains one of these words, for example "Engineering".

## `includeDetails` (type: `boolean`):

For companies: one extra request per job to get salary and hybrid/on-site workplace type. Descriptions, requirements and benefits are included even when this is off. Workable allows only a limited number of these requests per day; when the limit is hit, the Actor stops asking, keeps all jobs and marks the company as partial.

## `mode` (type: `string`):

"All jobs" returns every matching job. "Only changes" compares with the previous run of the same input and returns new, changed and removed jobs. The first changes run returns all jobs as new.

## `monitorStateKey` (type: `string`):

Optional. Runs with the same monitor name share memory. Leave empty to use the companies, searches and filters as the name. Letters, digits, - and \_ only.

## `includeUnchanged` (type: `boolean`):

Only for "Only changes" mode: also return jobs that did not change, marked unchanged.

## `maxJobsPerSource` (type: `integer`):

Stop each company or search after this many matching jobs (1–5000). The source is then marked partial.

## `maxJobsTotal` (type: `integer`):

Stop the whole run after this many matching jobs (1–5000). Bigger jobs: split companies or searches into several runs.

## Actor input object example

```json
{
  "companies": [
    "costello-medical"
  ],
  "postedWithin": "any",
  "includeDetails": false,
  "mode": "all",
  "includeUnchanged": false,
  "maxJobsPerSource": 1000,
  "maxJobsTotal": 5000
}
```

# Actor output Schema

## `jobs` (type: `string`):

No description

## `output` (type: `string`):

No description

## `runSummary` (type: `string`):

No description

# 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 = {
    "companies": [
        "costello-medical"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("cliqtomedia/workable-jobs-monitor-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 = { "companies": ["costello-medical"] }

# Run the Actor and wait for it to finish
run = client.actor("cliqtomedia/workable-jobs-monitor-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "companies": [
    "costello-medical"
  ]
}' |
apify call cliqtomedia/workable-jobs-monitor-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,cliqtomedia/workable-jobs-monitor-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

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