# Workable Jobs Scraper — Search 170K Jobs, No Slug (`nomad-agent/workable-jobs-scraper`) Actor

Search all ~170,000 live Workable jobs by keyword, location, workplace type and recency — no company slug needed — or scrape specific company boards. Multi-country postings are billed once, not once per country. Delta monitoring, BYOK AI enrichment, MCP-ready.

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

## Pricing

from $2.00 / 1,000 job results

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/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

## Workable Jobs Scraper — Search 170K Jobs, No Slug

> **Claude / Codex skill to describe and setup this actor: [SKILL.md](https://github.com/Exdenta/OinkAIJobSearch/blob/main/skill/workable-jobs-scraper/SKILL.md)**

**Search every job on Workable by keyword — you do not need to know a company slug.** Workable's public index carries roughly **170,000 live postings** from tens of thousands of SMBs and scale-ups; this Actor searches all of it, or scrapes specific company boards directly if you already know who you want.

No login, no API key, no proxies. Public APIs only.

```json
{ "searchQuery": "python engineer", "searchWorkplace": "remote", "searchPostedDays": 7 }
```

That's a complete run. No slug hunting.

### Why this one

Most Workable scrapers make you supply a company slug — so you can't use them until you already know which companies you want. The ones that *do* search have a quieter problem, and it's on your invoice.

**Workable's index lists a posting once per country it's open in** — each copy with its own id and URL, all the same job. One posting in a recent run was listed in **36 countries**. A scraper that reads the index literally returns that job 36 times and bills you 36 times.

This Actor folds them back into **one row per real job**, every country in a `locations` array. Measured on a live run: **46 jobs returned, 46 results billed — those 46 jobs occupy 363 rows in Workable's index.** Billed per row, the same jobs cost 7.9× more. On a broad unfiltered search, roughly a third of index rows are duplicates; on a narrow one it's far more.

| | This Actor |
|---|---|
| Search all of Workable, no slug | ✅ |
| Scrape specific company boards | ✅ (batch, many at once) |
| One row per job, not per country | ✅ — the 7.9× above |
| `workplace` (remote / hybrid / on-site) | ✅ stated by Workable, not guessed |
| Full description + requirements + benefits | ✅ |
| Company website (lead-gen) | ✅ on every row |
| Delta mode — only pay for *new* postings | ✅ |
| AI enrichment (skills, seniority, salary) | ✅ opt-in, bring your own key |

### Two ways to run it

**1. Search (no slug needed)** — the whole Workable index:

```json
{
  "searchQuery": "registered nurse",
  "searchLocation": "London",
  "searchWorkplace": "hybrid",
  "searchPostedDays": 14,
  "maxItems": 100
}
```

**2. Company boards** — when you already know the companies:

```json
{ "companies": ["netguru", "typeform"], "keyword": "engineer" }
```

Find a slug by opening the company's careers page and reading it out of `apply.workable.com/<slug>/`. Full board URLs work too — they're reduced to the slug for you. You can combine both modes in one run; a posting found by both is returned (and billed) once.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `searchQuery` | string | — | **Free-text search across every job on Workable — no company slug needed.** e.g. `python engineer`. |
| `searchLocation` | string | — | City, region or country to search in, e.g. `London`, `Germany`. |
| `searchWorkplace` | string | `any` | `any` / `remote` / `hybrid` / `on_site`. An exact filter — Workable states this per posting. |
| `searchPostedDays` | integer | — | Only search postings published in the last N days. |
| `companies` | array | — | Optional. Workable board slugs (full board URLs also accepted). |
| `keyword` | string | — | Case-insensitive substring match on the job title. Applies to both modes. |
| `titleExclude` | array | — | Drop postings whose title contains any of these substrings. |
| `locationFilter` | string | — | Case-insensitive substring match on the location. |
| `postedSince` | integer | — | Keep only postings published within N days. Postings with no date are dropped when set. |
| `remoteOnly` | boolean | `false` | Fully-remote only. Hybrid is **not** counted as remote — use `searchWorkplace` for that. |
| `includeDescription` | boolean | `true` | Include the full plain-text description. Turn off for lighter output. |
| `maxItemsPerCompany` | integer | `100` | Cap postings per company board (0 = no cap). Each result is billed. |
| `maxItems` | integer | `200` | Hard cap on total postings returned (0 = no cap). Each result is billed. In search mode this also bounds how deep the Actor pages. |
| `onlyNewSinceLastRun` | boolean | `false` | Delta/monitoring mode — see below. |
| `aiEnrichment` | boolean | `false` | Opt-in BYOK AI fields — see below. |
| `aiProvider` | string | `anthropic` | `anthropic` or `mistral`. |
| `anthropicApiKey` | string (secret) | — | Your Anthropic key. Billed by Anthropic, not by this Actor. |
| `aiModel` | string | `claude-haiku-4-5-20251001` | `claude-haiku-4-5-20251001` (fast/cheap) or `claude-sonnet-4-5`. |
| `mistralApiKey` | string (secret) | — | Your Mistral key. Billed by Mistral, not by this Actor. |
| `mistralModel` | string | `mistral-small-latest` | `mistral-small-latest` / `mistral-medium-latest` / `mistral-large-latest`. |
| `concurrency` | integer | `8` | Company boards fetched in parallel (advanced). |

### Output

One flat JSON record per **real job** (not per index row):

| Field | Meaning |
|---|---|
| `title` | Job title as posted |
| `company` | Company display name |
| `companyWebsite` | Company website — present on every search result, useful for lead-gen |
| `companyLogo` | Company logo URL (company-board mode) |
| `location` | Primary location text |
| `locations` | **Every** location the posting is open in — the countries a naive scraper would bill you for separately |
| `locationCity` / `locationRegion` / `locationCountry` | Structured location, straight from Workable |
| `workplace` | `remote` / `hybrid` / `on_site` — **stated by Workable, never inferred** (search mode) |
| `remote` | `true` only for fully-remote. Hybrid is `false`. `null` when Workable states neither |
| `employmentType` | Full-time / Part-time / Contract etc. where stated |
| `department` | Department or team where provided |
| `snippet` | Full plain-text description |
| `requirements` | Requirements section, where Workable states one separately |
| `benefits` | Benefits section, where Workable states one separately |
| `industry` | Company industry (company-board mode) |
| `experience` / `education` | Experience level and education requirement, where stated (company-board mode) |
| `postedAt` | First-published date (`YYYY-MM-DD`) |
| `url` | Link to the posting |
| `applyUrl` | Direct link to the application form |
| `id` | Workable's own posting id |
| `globalId` | Stable composite id — the delta-mode dedupe key |
| `warnings` | Data-quality notes for this record (empty array when there's nothing to flag) |
| `isNew` | Only when `onlyNewSinceLastRun` is on — always `true` |
| `ai*` | Only when `aiEnrichment` is on — see below |

### Call it from code

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("nomad-agent/workable-jobs-scraper").call(run_input={
    "searchQuery": "python engineer",
    "searchWorkplace": "remote",
    "maxItems": 50,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["company"], "|", item["title"], "|", item["workplace"], item["url"])
```

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/nomad-agent~workable-jobs-scraper/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"searchQuery": "python engineer", "searchWorkplace": "remote"}'
```

### Output example

```json
{
  "ats": "workable",
  "company": "payabl.",
  "companyWebsite": "http://payabl.com",
  "id": "5b10e8f7-627e-4cd3-8f09-3c40c96f71f5",
  "title": "Senior Backend Python Engineer (Core Gateway)",
  "department": "Engineering",
  "location": "Czechia",
  "locations": ["Czechia", "Germany", "United Kingdom", "Romania", "Serbia", "Netherlands"],
  "locationCountry": "Czechia",
  "url": "https://jobs.workable.com/view/cfdWh7wNW4V1G8zXPmvN1n/...",
  "applyUrl": "https://jobs.workable.com/view/cfdWh7wNW4V1G8zXPmvN1n/...",
  "postedAt": "2026-06-22",
  "employmentType": "Full-time",
  "workplace": "remote",
  "remote": true,
  "snippet": "About payabl. We are a fast-growing fintech...",
  "requirements": "5+ years of Python...",
  "benefits": "Private health insurance...",
  "globalId": "workable:search:5b10e8f7-627e-4cd3-8f09-3c40c96f71f5",
  "warnings": []
}
```

That is **one** row. A scraper that reads Workable's index literally would have returned it six times — once per country — and billed you six times.

### Delta mode / monitoring

Set `onlyNewSinceLastRun: true` to turn this Actor into a "what's new" monitor. Postings already seen on a previous run made with this flag on are dropped **before** push — you are not billed for them. Pair it with an Apify schedule (cron) and every run only returns, and only charges for, postings that appeared since the last flagged run.

Seen postings are tracked in a dedicated key-value store keyed by `globalId`, capped at ~50,000 entries (oldest evicted first). The first flagged run has nothing to compare against, so it emits everything. Runs with the flag off never read or write this cache — toggling it between runs is safe.

Delta mode is applied *while* the Actor pages, not after: a search that has to page deep to find new postings keeps paging until it has them, rather than handing back an empty run.

### AI enrichment

Turn on `aiEnrichment` and supply your own `anthropicApiKey` (or `mistralApiKey` with `aiProvider: "mistral"`) to add AI-extracted fields to every posting:

| Field | Meaning |
|---|---|
| `aiKeySkills` | Skills/technologies explicitly named in the posting — never invented |
| `aiExperienceLevel` | `entry` / `mid` / `senior` / `lead` / `unknown` |
| `aiWorkArrangement` | `onsite` / `hybrid` / `remote` / `unknown` |
| `aiVisaSponsorship` | `true`/`false` only when the posting states a policy, else `null` |
| `aiSalaryRange` | `{min, max, currency, period}` only from explicitly stated pay figures — never inferred |

The prompt is explicit about never guessing: when the text doesn't support a value you get `unknown` / `null` / an empty array, not a fabrication.

You usually **don't need AI for work arrangement** — search mode returns Workable's own `workplace` field for free, and it's authoritative rather than inferred.

Postings are batched (~12 per call). **Your key is billed by that provider, not by this Actor.** Rough cost with Haiku or Mistral Small: ~100 postings well under $0.05 in provider tokens; Sonnet/Mistral Large roughly 4-5× that.

If `aiEnrichment` is on but no matching key is available, enrichment is skipped: you get one dataset row explaining why, and every posting is still returned normally without the `ai*` fields.

### Warning rows

Alongside normal postings, this Actor can push rows that are all `null` except `company`/`ats`/`warnings` — same flat schema, so a dataset-only consumer sees every problem without reading the run log:

| Trigger | Example `warnings` |
|---|---|
| A requested company slug 404'd | `["not found on any ATS probed (workable): 'acme-corp' (404 on every probe)"]` |
| `maxItemsPerCompany` cut postings for one company | `["truncated for 'acme-corp': maxItemsPerCompany=100 returned 100 of 137 matching postings"]` |
| `maxItems` cut the run | `["truncated: maxItems=200 returned 200 of 3401 matching postings"]` |
| `aiEnrichment` requested with no key | `["aiEnrichment skipped: no anthropicApiKey or mistralApiKey provided"]` |

**None of these rows are billed** — only genuine postings are.

### Integrations

Export as JSON, CSV or Excel, or pipe into Make, Zapier or n8n. Call it synchronously with `run-sync-get-dataset-items`, or plug it into any AI agent through the [Apify MCP server](https://apify.com/apify/actors-mcp-server).

### Pricing

Pay per event — the current rate is shown in the **Pricing** section of this page. No subscription, no minimum.

**Compare on cost per *real job*, not cost per row.** Workable's index repeats a multi-country posting once per country, and a scraper that bills per index row bills you for every one of them. A real run of this Actor: **46 jobs returned, 46 results billed — but those 46 jobs occupy 363 rows in Workable's index** (one posting alone is open in 36 countries). Billed per row, the same 46 jobs cost **7.9× more**.

So a cheaper-looking headline rate is often the more expensive scraper.

If you turn on `aiEnrichment`, your Anthropic/Mistral key is billed separately by that provider. Delta mode only *reduces* cost — already-seen postings are dropped before the billed push.

### Use cases

- Find who's hiring for a role across all of Workable, without a company list
- Recruiting-agency lead generation (company website on every row)
- Job-board aggregation and "new postings" alerting (delta mode + cron)
- Hiring/market research on SMBs and scale-ups (Workable is strong in Europe)

### FAQ

**Do I need a company slug?**
No. `searchQuery` searches every company on Workable. Slugs are optional, for when you want specific boards.

**Is it legal to scrape Workable jobs?**
The data comes from Workable's official, public, unauthenticated JSON APIs — the same data any visitor sees on a careers page. Review the terms for your use case.

**Do I need an API key or login?**
No. Public APIs, no authentication of any kind.

**Why does one job list several countries?**
Because it's open in all of them. Workable's index repeats such a posting once per country; this Actor returns it once with every country in `locations`, so you aren't billed repeatedly for the same job.

**How fresh is the data?**
Every run hits Workable live. No caching layer in between.

**Something broken or missing?**
Open an issue on the **Issues** tab — it's monitored and fixes ship fast.

### Related Actors

- [Greenhouse Jobs Scraper — Company Job Boards](https://apify.com/nomad-agent/greenhouse-jobs-scraper)
- [Lever Jobs Scraper — Company Job Postings API](https://apify.com/nomad-agent/lever-jobs-scraper)
- [Ashby Jobs Scraper — Company Job Boards API](https://apify.com/nomad-agent/ashby-jobs-scraper)
- [Company Careers Scraper — Greenhouse Lever Ashby](https://apify.com/nomad-agent/company-careers-bundle)
- [LinkedIn Jobs Scraper — No Login, No Cookies](https://apify.com/nomad-agent/linkedin-scraper)

***

**From the maker of [Oink](https://github.com/Exdenta/OinkAIJobSearch)** — an open-source, AI-powered job-search bot for Telegram that runs on these Actors. [Try the free bot](https://t.me/job_search_everyday_bot), get a managed instance at [oinkjobsearch.com](https://oinkjobsearch.com), or browse the [full catalog of 50+ Actors](https://apify.com/nomad-agent).

# Actor input Schema

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

Free-text search across <b>every</b> job on Workable (~170,000 live postings from all companies) — you do <b>not</b> need to know a company slug. Example: <code>python engineer</code>, <code>registered nurse</code>. Leave empty to scrape only the specific company boards listed under "Company boards" below.

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

City, region or country to search in, e.g. <code>London</code>, <code>Germany</code>, <code>New York</code>. Only applies to the search query above.

## `searchWorkplace` (type: `string`):

Restrict the search to one workplace type. Workable states this per posting, so this is an exact filter, not a guess.

## `searchPostedDays` (type: `integer`):

Only search postings published within the last N days (e.g. <code>7</code>). Leave empty for no recency limit. Only applies to the search query above.

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

Optional — scrape specific companies' Workable boards by slug. Open the company's careers page and look for apply.workable.com/<slug>/ in the URL. Full board URLs are also accepted. Leave empty if you're using the search query above.

## `keyword` (type: `string`):

Optional case-insensitive substring match on the job title (e.g. <code>engineer</code>).

## `titleExclude` (type: `array`):

Drop postings whose title contains any of these substrings (case-insensitive). Example: \[<code>intern</code>, <code>staffing</code>].

## `locationFilter` (type: `string`):

Optional case-insensitive substring match on the location (e.g. <code>remote</code>, <code>london</code>).

## `postedSince` (type: `integer`):

Only keep postings first published within this many days. Leave empty (or 0) for no date filter. When this is set, postings the source didn't give a posting date for are dropped rather than guessed at.

## `remoteOnly` (type: `boolean`):

Keep only fully-remote postings. In search mode this uses Workable's own workplace field (hybrid is NOT counted as remote — use "Search workplace type" above to target hybrid); on company boards it uses Workable's telecommuting flag. Postings where Workable states neither are excluded.

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

Include the posting's full plain-text description. Turn off for lighter, faster output. Search mode also returns requirements and benefits sections when Workable states them.

## `maxItemsPerCompany` (type: `integer`):

Cap postings returned per company. Each posting returned is a billed result, so this keeps one large board from dominating the run's cost. 0 = no cap.

## `maxItems` (type: `integer`):

Hard cap on total postings returned across the search and all company boards. Each posting returned is billed as a paid result — raise this only as high as you actually need. In search mode this also bounds how deep the Actor pages into the index. 0 = no cap (not recommended with a broad search query).

## `onlyNewSinceLastRun` (type: `boolean`):

Delta/monitoring mode: only output postings not seen in a previous run that also had this flag on. Already-seen postings are dropped before push (not billed), so this is the cheapest way to run this Actor on a cron schedule and only pay for genuinely new postings. State is tracked per Actor in a dedicated key-value store, keyed by each posting's globalId. See README “Delta mode / monitoring”.

## `aiEnrichment` (type: `boolean`):

Adds aiKeySkills / aiExperienceLevel / aiWorkArrangement / aiVisaSponsorship / aiSalaryRange to every posting via the Anthropic or Mistral API (pick which below). Requires your own API key for the provider you pick — billed separately by that provider, not by this Actor (see README “AI enrichment”). If turned on without a matching key, enrichment is skipped (with a warning) and postings are still returned normally, without the ai\* fields.

## `aiProvider` (type: `string`):

Which AI provider runs enrichment (only relevant when “AI enrichment” is on). <code>anthropic</code> (default) uses Claude via anthropicApiKey. <code>mistral</code> uses a Mistral model via mistralApiKey instead — pick this if you'd rather bring a Mistral key than an Anthropic one. <code>openai</code> uses a GPT model via openaiApiKey.

## `anthropicApiKey` (type: `string`):

Your Anthropic API key (sk-ant-…). Only used when “AI enrichment” is on and aiProvider is <code>anthropic</code>; billed separately by Anthropic. Not required unless aiEnrichment is on.

## `aiModel` (type: `string`):

Claude model used for AI enrichment when aiProvider is <code>anthropic</code> (only relevant when “AI enrichment” is on). Haiku is fast and inexpensive; Sonnet gives higher-quality extraction on longer, more nuanced descriptions.

## `mistralApiKey` (type: `string`):

Your Mistral API key. Only used when “AI enrichment” is on and aiProvider is <code>mistral</code>; billed separately by Mistral. Not required unless aiEnrichment is on with aiProvider=mistral.

## `mistralModel` (type: `string`):

Mistral model used for AI enrichment when aiProvider is <code>mistral</code> (only relevant when “AI enrichment” is on). Small is the default — testing found it matches larger Mistral models on this extraction task (small, well-scoped fields) at a fraction of the cost.

## `openaiApiKey` (type: `string`):

Your OpenAI API key (sk-…). Only used when “AI enrichment” is on and aiProvider is <code>openai</code>; billed separately by OpenAI. Not required unless aiEnrichment is on with aiProvider=openai.

## `openaiModel` (type: `string`):

OpenAI model used for AI enrichment when aiProvider is <code>openai</code> (only relevant when “AI enrichment” is on). Defaults to <code>gpt-4.1-mini</code> — cheap, fast and ample for this extraction task. Any chat-completions model works, including the gpt-5 family (e.g. <code>gpt-5.4-mini</code>).

## `concurrency` (type: `integer`):

How many companies to fetch at the same time. Higher is faster but hits the source API harder — the default is a safe, fast setting for almost every run.

## Actor input object example

```json
{
  "searchQuery": "python engineer",
  "searchWorkplace": "any",
  "companies": [
    "netguru",
    "typeform"
  ],
  "titleExclude": [
    "intern",
    "staffing"
  ],
  "remoteOnly": false,
  "includeDescription": true,
  "maxItemsPerCompany": 100,
  "maxItems": 200,
  "onlyNewSinceLastRun": false,
  "aiEnrichment": false,
  "aiProvider": "anthropic",
  "aiModel": "claude-haiku-4-5-20251001",
  "mistralModel": "mistral-small-latest",
  "openaiModel": "gpt-4.1-mini",
  "concurrency": 8
}
```

# Actor output Schema

## `dataset` (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 = {
    "searchQuery": "python engineer",
    "companies": [
        "netguru",
        "typeform"
    ],
    "titleExclude": [
        "intern",
        "staffing"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("nomad-agent/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": "python engineer",
    "companies": [
        "netguru",
        "typeform",
    ],
    "titleExclude": [
        "intern",
        "staffing",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("nomad-agent/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": "python engineer",
  "companies": [
    "netguru",
    "typeform"
  ],
  "titleExclude": [
    "intern",
    "staffing"
  ]
}' |
apify call nomad-agent/workable-jobs-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

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