# Workable, SmartRecruiters & Recruitee Jobs Scraper (`kasumilab/workable-smartrecruiters-recruitee-jobs-scraper`) Actor

Export all open jobs from company career pages hosted on Workable, SmartRecruiters or Recruitee via their official public job APIs. Title, location, department, remote flag, employment type, salary (where published) and full description. No login, no proxy.

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

## Pricing

from $2.00 / 1,000 jobs

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, SmartRecruiters & Recruitee Jobs Scraper

Export every open job from company career pages hosted on **Workable**, **SmartRecruiters** or **Recruitee**, as clean rows with title, location, department, remote flag, employment type, salary (where published) and the full description.

The Actor reads the official public job APIs of the three systems (the same endpoints the career pages use). No API key, no login and no proxy are needed. Three companies with 25 jobs each take about 5 seconds.

### What you can do with it

- Watch the career pages of target companies and get new openings into Slack, Airtable or email.
- Build a niche job board from companies that hire in your field.
- Collect salary ranges and locations across many employers.
- Give an AI agent a clean list of jobs to match against a resume.

Thousands of companies use these systems: Workable is common among European and US startups, SmartRecruiters among large enterprises (Ubisoft, Bosch, Visa...), Recruitee among European scale-ups.

### Input

| Field | What it does |
|---|---|
| `companies` | Career page URLs (`apply.workable.com/acme`, `jobs.smartrecruiters.com/Acme`, `acme.recruitee.com`), `workable:acme` / `smartrecruiters:Acme` / `recruitee:acme`, or a plain slug `acme` that is tried on all three systems. |
| `titleKeywords` | Keep only jobs whose title contains one of these words. |
| `locationKeywords` | Keep only jobs whose location, country or workplace type contains one of these words, for example `remote`, `berlin`, `netherlands`. |
| `postedWithinDays` | Keep only jobs published in the last N days. `0` keeps all. |
| `includeDescription` | Add the description as HTML and plain text. For SmartRecruiters this costs one extra request per job. |
| `maxItemsPerCompany` | Newest jobs first per company. `0` means no limit. |
| `maxItems` | Stop after this many jobs in total. `0` means no limit. |

Remote engineering jobs at three companies, newest first:

```json
{
  "companies": ["https://apply.workable.com/skroutz/", "smartrecruiters:Ubisoft2", "recruitee:jobs"],
  "titleKeywords": ["engineer", "developer"],
  "locationKeywords": ["remote"],
  "postedWithinDays": 14
}
```

### Output

One item per job. The same fields are filled for all three systems; a field a system does not provide is `null`.

```json
{
  "ats": "smartrecruiters",
  "company": "Ubisoft2",
  "companyName": "Ubisoft",
  "id": "744000155806403",
  "title": "Spécialiste en sécurité – Fraude numérique",
  "department": "Ubisoft",
  "team": "Information Technology",
  "location": "Montreal, QC, Canada",
  "locations": ["Montreal, QC, Canada"],
  "country": "CA",
  "remote": false,
  "workplaceType": null,
  "employmentType": "Full-time",
  "experienceLevel": "Mid-Senior Level",
  "postedAt": "2026-10-15T16:24:49.092Z",
  "updatedAt": null,
  "url": "https://jobs.smartrecruiters.com/Ubisoft2/744000155806403-specialiste-en-securite-fraude-numerique",
  "applyUrl": "https://jobs.smartrecruiters.com/Ubisoft2/744000155806403-specialiste-en-securite-fraude-numerique?oga=true",
  "salaryMin": null,
  "salaryMax": null,
  "salaryCurrency": null,
  "salaryInterval": null,
  "salarySummary": null,
  "refNumber": "REF31569U",
  "descriptionHtml": "<h3>Company Description</h3><p>Ubisoft est une référence mondiale...</p>",
  "descriptionText": "Company Description\nUbisoft est une référence mondiale...",
  "scrapedAt": "2026-10-16T08:21:28.121Z"
}
```

Recruitee jobs include `salaryMin`, `salaryMax`, `salaryCurrency` and `salaryInterval` when the company publishes a range. Workable jobs include `experienceLevel` and `employmentType` and the description combines the description, requirements and benefits sections.

### Finding the right slug

- **Workable**: the career page is `https://apply.workable.com/<slug>/`. The slug is the last part of that URL.
- **SmartRecruiters**: the career page is `https://jobs.smartrecruiters.com/<Company>`. The company identifier is case-sensitive and sometimes has a suffix, for example `Ubisoft2`.
- **Recruitee**: the API lives on `https://<slug>.recruitee.com`. Companies often use a custom domain such as `careers.example.com` for the page itself; the slug is then visible in links on that page or in its source.

A company that is not found on any of the three systems is reported in the run's status message. The run fails only when no company could be read.

### Limits and notes

- Only published, public jobs are returned (internal and draft jobs are not visible through these APIs).
- SmartRecruiters returns an empty list for unknown company identifiers; the Actor reports that as "no public job board found".
- Workable's API returns the whole board in one call, so large boards are fast. SmartRecruiters descriptions cost one request per job; turn `includeDescription` off for a quick list.
- Dates: `postedAt` is the publish date given by the system (Workable gives a date without time).

### Pricing

You pay per job saved to the dataset, plus a tiny fee per run start. Use the keyword, date and limit fields to control the number of results.

# Actor input Schema

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

Career page URLs (apply.workable.com/acme, jobs.smartrecruiters.com/Acme, acme.recruitee.com), or `workable:acme` / `smartrecruiters:Acme` / `recruitee:acme`. A plain company slug such as `acme` is tried on all three systems.

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

Keep only jobs whose title contains at least one of these words (case-insensitive). Leave empty to keep all jobs.

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

Keep only jobs whose location, country or workplace type contains at least one of these words, for example `remote`, `berlin`, `netherlands`. Leave empty to keep all locations.

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

Keep only jobs published in the last N days. 0 keeps all jobs.

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

Add the full description as HTML and as plain text. For SmartRecruiters this needs one extra request per job.

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

Newest jobs first. 0 means no limit per company.

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

The run stops after saving this many jobs. 0 means no limit.

## Actor input object example

```json
{
  "companies": [
    "https://apply.workable.com/skroutz/",
    "https://jobs.smartrecruiters.com/Ubisoft2",
    "https://jobs.recruitee.com"
  ],
  "titleKeywords": [],
  "locationKeywords": [],
  "postedWithinDays": 0,
  "includeDescription": true,
  "maxItemsPerCompany": 25,
  "maxItems": 100
}
```

# Actor output Schema

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

All jobs saved by this run, as JSON. Add ?format=csv or ?format=xlsx for other formats.

# 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": [
        "https://apply.workable.com/skroutz/",
        "https://jobs.smartrecruiters.com/Ubisoft2",
        "https://jobs.recruitee.com"
    ],
    "maxItemsPerCompany": 25,
    "maxItems": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("kasumilab/workable-smartrecruiters-recruitee-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 = {
    "companies": [
        "https://apply.workable.com/skroutz/",
        "https://jobs.smartrecruiters.com/Ubisoft2",
        "https://jobs.recruitee.com",
    ],
    "maxItemsPerCompany": 25,
    "maxItems": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("kasumilab/workable-smartrecruiters-recruitee-jobs-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": [
    "https://apply.workable.com/skroutz/",
    "https://jobs.smartrecruiters.com/Ubisoft2",
    "https://jobs.recruitee.com"
  ],
  "maxItemsPerCompany": 25,
  "maxItems": 100
}' |
apify call kasumilab/workable-smartrecruiters-recruitee-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,kasumilab/workable-smartrecruiters-recruitee-jobs-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/tcHrYEMVw2JhCfyxL/builds/8y3cUSJTpQhPicOGL/openapi.json
