# All Jobs Scraper (`techforce.global/all-jobs-scraper`) Actor

All-in-one job scraper that aggregates 26+ job boards. Indeed, Adzuna, USAJobs, Reed, Remotive, and more into one de-duplicated feed by keyword. Get title, company, salary, location, remote status, and posting date, ready for JSON, CSV, Excel, or API/webhook delivery into Notion, Slack, or Airtable.

- **URL**: https://apify.com/techforce.global/all-jobs-scraper.md
- **Developed by:** [Techforce Global](https://apify.com/techforce.global) (community)
- **Categories:** Jobs, Agents, Automation
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.10 / 1,000 results

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 a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use 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

### All Jobs Scraper & MCP Connector

Search **one keyword across dozens of job boards at once** and get back a single, de-duplicated, normalized list of listings — title, company, location, salary, description, URL, posted date, and job type. **No API keys to hunt down, no ten browser tabs, no copy-pasting into a spreadsheet.**

Built for job seekers, recruiters, sourcers, and market researchers who need a broad, current view of "what's open right now" without visiting every site by hand.

> **Type a keyword → get jobs from 26 sources, de-duplicated and normalized → deliver them straight into Notion, Slack, Airtable, or your CRM.**

---

### ⭐ Why This Actor?

- ✅ **Just type a keyword** — `keyword` is the only required field. Everything else (location, country, remote-only, job type, sources, result cap) is optional.
- ✅ **26 sources, one call** — aggregates [Remotive](https://remotive.com), [RemoteOK](https://remoteok.com), [Arbeitnow](https://www.arbeitnow.com), [Jobicy](https://jobicy.com), [We Work Remotely](https://weworkremotely.com), [The Muse](https://www.themuse.com), [Adzuna](https://www.adzuna.com), [USAJobs](https://www.usajobs.gov), [Reed.co.uk](https://www.reed.co.uk), and [Jooble](https://jooble.org) **on by default with zero setup**, plus optional [Arbetsformedlingen](https://arbetsformedlingen.se) (Sweden), [Arbeitsagentur](https://www.arbeitsagentur.de) (Germany), [France Travail](https://francetravail.fr), [VDAB](https://www.vdab.be) (Belgium), [Indeed](https://www.indeed.com), [Freelancer.com](https://www.freelancer.com), [Foundit](https://www.foundit.in) (India), [Bayt.com](https://www.bayt.com) (MENA + India), [Job Bank](https://www.jobbank.gc.ca) (Canada), [jobs.ch](https://www.jobs.ch) (Switzerland), [kariyer.net](https://www.kariyer.net) (Turkey), [Talent.com](https://www.talent.com), [OnlineJobs.ph](https://www.onlinejobs.ph) (Philippines), [Glints](https://glints.com) (Southeast Asia), [CV-Library](https://www.cv-library.co.uk) (UK), and [Talroo/Jobs2Careers](https://www.talroo.com) (US, needs your own free Publisher account).
- ✅ **One blocked source never sinks the run** — each source runs independently and fails in isolation, so you still get results from everything else that succeeded.
- ✅ **Clean, normalized output** — every listing is mapped to the same fields (title, company, location, remote, job_type, salary, description, url, posted_date, tags) regardless of which board it came from.
- ✅ **De-duplicated and pooled** — results from all selected sources are merged and de-duplicated before your `max_results` cap is applied.
- ✅ **Bring your own keys, or don't** — Adzuna, USAJobs, Reed, Jooble, Arbeitsagentur, and France Travail already work out of the box; set your own credentials only if you want higher rate limits or a different account.
- ✅ **Deliver anywhere via MCP connectors** — push results straight into Notion, Slack, Airtable, Jira, Linear, and more.
- ✅ **Export-ready** — JSON, CSV, Excel, HTML, or direct API integration for your own pipeline.

---

### 📝 Use Cases & ROI

| Use Case | Time Saved | What You Get |
| --- | --- | --- |
| **Job search** | 2–4 hrs/search | One de-duplicated list instead of repeating the same search on ten sites |
| **Recruiting & sourcing** | 3–6 hrs/role | Competitor hiring activity and open-role visibility across boards and regions |
| **Market & compensation research** | 4–8 hrs/report | Structured salary, location, and remote-share data by role, ready to analyze |
| **Product / dashboard feeds** | Ongoing | A clean JSON feed you can refresh on a schedule via the Apify API |

---

### 🚀 How to Use

1. Click **Try for free** (or **Start**) on this Actor's page.
2. Enter a **Keyword** (e.g. `"Data Engineer"`) — this is the only required field.
3. _(Optional)_ Set **Location** or **Country**, toggle **Remote only**, pick a **Job type**, and set **Max results** (default: `100`).
4. _(Optional)_ Choose which **Sources** to query, or leave the ten default sources (all work with zero setup).
5. _(Optional)_ Pick an **MCP connector** under **Delivery** to push results into Notion, Slack, Airtable, etc.
6. Click **Start** and wait for the run to finish.
7. Open the **Dataset** tab to browse, filter, or export your results (JSON, CSV, Excel, HTML, and more).

> 💡 First time with a connector? Run once with a connector selected and no tool name set — the run log prints the connector's available tool names and, once you set a valid one, that tool's own full JSON Schema too.

---

### 🧩 Input Configuration

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `keyword` | String | ✔️ Yes | Job title, skill, or company name to search for. |
| `location` | String | Optional | Free-text city/region filter. Leave blank for a broad/remote search. |
| `country` | Enum | Optional | Scopes country-aware sources (Adzuna, USAJobs) and acts as a location fallback for others. Leave blank for each source's own broad default. |
| `remote_only` | Boolean | Optional | Keep only remote (or unspecified-remote) jobs. Default: `false`. |
| `job_type` | Enum | Optional | `all`, `fulltime`, `parttime`, `contract`, `internship`. Default: `all`. |
| `max_results` | Integer | Optional | Cap on total results across all sources, after pooling and de-duplication. Default: `100`. |
| `sources` | Array | Optional | Which job boards to query — see the source list above. Defaults to the ten zero-setup sources. |
| `adzuna_app_id` / `adzuna_app_key` | String | Optional | Adzuna already works out of the box; set your own to use your own account instead. |
| `usajobs_email` / `usajobs_api_key` | String | Optional | USAJobs already works out of the box; set your own to use your own account instead. |
| `reed_api_key` | String | Optional | Reed.co.uk (UK) already works out of the box; set your own to use your own account instead. |
| `jooble_api_key` | String | Optional | Jooble already works out of the box; set your own to use your own account instead. |
| `arbeitsagentur_api_key` | String | Optional | Arbeitsagentur (Germany, best-effort) already works out of the box; set your own to use your own account instead. |
| `francetravail_client_id` / `francetravail_client_secret` | String | Optional | France Travail (France, best-effort) already works out of the box; set your own to use your own account instead. |
| `vdab_client_id` / `vdab_bearer_token` | String | Optional | VDAB (Belgium, best-effort) is attempted keyless by default; add these (from developer.vdab.be) if the keyless attempt returns a 401. |
| `themuse_api_key` | String | Optional | The Muse works keyless (500 req/hour); add your own free key for a higher 3,600 req/hour limit. |
| `talroo_publisher_id` / `talroo_publisher_password` | String | Required for Talroo | Talroo/Jobs2Careers (US only) has no built-in fallback — apply free at talroo.com/publish and enter your Feed Manager credentials. |
| `talroo_ip` | String | Optional | End-user IP Talroo's API expects for location/analytics; a generic default is used if unset. |
| `proxyConfiguration` | Object | Optional | Apify Proxy. `indeed` requests its own Residential proxy automatically if unset; several best-effort sources can also use it if configured. |
| `mcpConnector` | Connector | Optional | Deliver scraped jobs into a connector you've authorized (Notion, Slack, Airtable, etc.) — see **MCP connector delivery** below. |
| `deliveryMode` | Enum | Optional | `perJob`, `chunked`, `summary`, or `none` (default) — how results are sent to the connector. |
| `mcpTool` | String | Optional | Name of the tool to call on the connector. |
| `mcpArguments` | Object | Optional | Arguments passed to that tool, with `{placeholder}` support. |
| `mcpMessageTemplate` | String | Optional | Template rendered into the `{message}` placeholder. |

Freelancer.com, Foundit (India), Bayt.com (MENA + India), Job Bank (Canada), jobs.ch (Switzerland), kariyer.net (Turkey), Talent.com, OnlineJobs.ph (Philippines), Glints (Southeast Asia), and CV-Library (UK) are all fully keyless best-effort sources with no credentials to configure — each scrapes the same public pages or internal API its own site uses.

#### Example — Basic search

```json
{
  "keyword": "Data Engineer",
  "country": "United States",
  "remote_only": false,
  "job_type": "all",
  "max_results": 50,
  "sources": ["remotive", "remoteok", "arbeitnow", "jobicy", "weworkremotely"]
}
````

***

### 🔌 MCP Connector Delivery

The dataset is always saved regardless of these settings — connector delivery is an additional, optional step. Pick a connector under **Delivery (optional)** in the Input tab, then set:

- **`deliveryMode`** — `perJob` (one connector call per job, e.g. one Notion page per listing), `chunked` (splits the whole job list across a few calls so a connector never times out or hits a block-count limit), `summary` (one call with every job as a single text block), or `none`.
- **`mcpTool`** — the connector tool to call. Run once with a connector selected and no tool name to see the available tool names logged.
- **`mcpArguments`** — a JSON object of arguments for that tool. Any string value can contain `{placeholders}` filled in per job (or per chunk/summary).
- **`mcpMessageTemplate`** — optional, rendered into the `{message}` placeholder.

**Placeholders** — `perJob` mode: `{title}`, `{company}`, `{location}`, `{url}`, `{source}`, `{jobType}`, `{remote}`, `{salary}`, `{description}`, `{postedDate}`, `{tags}`, `{keyword}`, `{jobCount}`, `{message}`. `summary`/`chunked` mode: `{jobsText}` (the formatted job list, or one part of it when chunked), `{keyword}`, `{jobCount}`, plus `{part}`/`{partCount}` in chunked mode.

`mcpArguments` must match the tool's real argument shape exactly, or every call fails with an MCP "Input validation error" (the dataset is unaffected — only delivery is skipped). Once `mcpTool` names a valid tool, the run log prints `Tool '...' expects arguments shaped like:` followed by that tool's own full JSON Schema (multi-line, so it isn't cut off by console line-length limits) — **read that schema from your own log before setting `mcpArguments`**, rather than copying an example verbatim, since connector tools do change their argument shape.

#### Example — Create a Notion page per job

`deliveryMode: "perJob"`, `mcpTool: "notion-create-pages"`. Confirmed from the tool's own logged schema:

- The call takes a top-level `"pages"` **array** (max 100, required) and an optional top-level `"parent"` object — `{"page_id": "..."}`, `{"database_id": "..."}`, or `{"data_source_id": "..."}`. Omit `"parent"` entirely to create private workspace-level pages.
- Each item inside `"pages"` only accepts `"properties"`, `"content"`, `"template_id"`, `"icon"`, and `"cover"` — a `"parent"` key inside a page item is rejected (`Unrecognized key: "parent"`; it belongs one level up, alongside `"pages"`).
- `"properties"` is a **flat** map of property name to string/number/array-of-strings/null (not the raw Notion API's nested `rich_text`/`title` objects) — match the names to your actual Notion database's columns.
- `"content"` is the page body, in Notion-flavored Markdown.

```json
{
  "parent": { "database_id": "YOUR_NOTION_DATABASE_ID" },
  "pages": [
    {
      "properties": {
        "Name": "{title}",
        "Company": "{company}",
        "Location": "{location}",
        "URL": "{url}",
        "Source": "{source}"
      },
      "content": "{description}"
    }
  ]
}
```

For `summary`/`chunked` mode with the same tool, put the formatted job list in the page content instead:

```json
{
  "parent": { "database_id": "YOUR_NOTION_DATABASE_ID" },
  "pages": [
    {
      "properties": { "Name": "{keyword} - jobs found" },
      "content": "{jobsText}"
    }
  ]
}
```

**Troubleshooting: "Provided database\_id X is a page, not a database"**

If the run log shows a Notion API error like:

```
Provided database_id 3a0e5ea6-3f43-8060-8fce-fe7061855e75 is a page, not a database.
Use the pages API instead, or pass the ID of the database itself.
```

the argument shape is correct, but the ID in `parent.database_id` points to a Notion *page*, not a database. Two ways to fix it:

- **You meant a database** — open the database as its own full-page view in Notion (not an embedded/linked view inside another page) and copy the ID from that page's URL. A linked database view shown inside a page has a different ID than the actual source database, which is the usual cause of this mix-up.
- **You meant that page** — switch `parent` to `page_id` instead of `database_id`. Pages created directly under a page (rather than as database rows) only support a `title` property, not custom columns like Company/Location:

  ```json
  {
    "parent": { "page_id": "3a0e5ea6-3f43-8060-8fce-fe7061855e75" },
    "pages": [
      { "properties": { "title": "{title} at {company}" }, "content": "{description}" }
    ]
  }
  ```

#### Example — Post a summary to Slack

```json
{
  "mcpTool": "send_message",
  "mcpArguments": { "channel": "#jobs", "text": "{message}" },
  "mcpMessageTemplate": "Found {jobCount} jobs for \"{keyword}\":\n\n{jobsText}"
}
```

***

### 📦 Output Fields

Each dataset item is a normalized job listing:

| Field | Description |
| --- | --- |
| `source` | Which job board the listing came from |
| `title` | Job title |
| `company` | Hiring company name |
| `location` | Location text as reported by the source |
| `remote` | `true`/`false`/`null` if remote status is unknown |
| `job_type` | Normalized: fulltime, parttime, contract, internship, or unknown |
| `salary` | Salary as reported (raw text or constructed range) |
| `description` | Cleaned job description/snippet |
| `url` | Link to the original listing |
| `posted_date` | ISO date the job was posted, if available |
| `tags` | Skill/category tags from the source, if any |
| `scraped_at` | ISO timestamp when this Actor collected the listing |

#### Example Output

```json
{
  "source": "remotive",
  "title": "Senior Data Engineer",
  "company": "Acme Corp",
  "location": "Remote (US)",
  "remote": true,
  "job_type": "fulltime",
  "salary": "$130,000 - $160,000",
  "description": "We're looking for a Senior Data Engineer to build and maintain our data pipelines...",
  "url": "https://remotive.com/remote-jobs/data/senior-data-engineer-12345",
  "posted_date": "2026-07-10T00:00:00+00:00",
  "tags": ["python", "sql", "airflow"],
  "scraped_at": "2026-07-15T09:00:00+00:00"
}
```

> You can download the dataset in various formats such as JSON, HTML, CSV, or Excel directly from the Console or via the API.

***

### 🔌 Integrations & Delivery

Deliver jobs into any MCP connector you've authorized in Apify — no glue code, no webhooks:

- **Notion** — create a page per job, or one summary page per search (use `chunked` mode for large result sets so Notion never times out)
- **Slack / Discord** — post individual jobs or a single search summary to a channel
- **Airtable / Google Sheets** — append a structured row per job
- **Jira / Linear / GitHub** — open tasks or issues from job listings
- …or any other MCP-compatible connector

Credentials stay private — delivery runs through the **Apify MCP Proxy**, so the Actor never sees your connector tokens. You can also consume the dataset directly via the **Apify API**, or wire it into **n8n, Zapier, and Make**.

***

### 💰 Pricing / Cost Estimation

This Actor makes lightweight HTTP/JSON calls (no headless browser) for nearly every source, so runs are fast and cheap on any Apify plan, including the free tier. Cost scales mainly with `max_results` and the number of `sources` selected — the default sources (no setup needed) typically finish a 100-result run in well under a minute. Enabling `indeed` adds noticeably more compute time (it drives a real headless browser) but no extra Apify cost beyond that compute time.

***

### 🛠️ Tips and Advanced Options

- Leave `sources` at the default ten (add Arbetsformedlingen if you're searching Sweden) for the fastest, most reliable runs — none of them need any setup and none are anti-bot protected.
- Adzuna, USAJobs, Reed.co.uk, Jooble, Arbeitsagentur, France Travail, and The Muse all work with no configuration — the Actor already has access set up, or they're fully keyless. Set your own key in the matching optional field if you'd rather use your own account (e.g. for higher rate limits).
- `arbeitsagentur`, `france_travail`, and `vdab` are best-effort sources — useful when they work, but don't rely on them as your only source.
- `freelancer`, `foundit`, `bayt`, `jobbank`, `jobs_ch`, `kariyer`, `talent_com`, `onlinejobsph`, and `glints` are also best-effort, fully keyless sources that scrape each site's own public pages or internal (undocumented) endpoints rather than a documented API — coverage and reliability vary by site, and several are scoped to a specific country/region regardless of your `country` input (Foundit and Job Bank scrapers in particular ignore `country`/`location` for search, relying on the central `location` filter to narrow results afterward).
- `cv_library` is best-effort **and the least reliable source here** — its real search flow sits behind a session/JS-driven process a plain HTTP scraper can't reliably reach, so expect little or no data from it.
- `talroo` (Jobs2Careers, US-only) has no built-in or keyless fallback — it requires your own free Publisher ID/Password. Without those set, this source is silently skipped.
- `indeed` runs a real headless browser instead of a plain HTTP request, since Indeed's pages are JS-rendered and behind bot detection — it's slower and more compute-intensive, so it's off by default. It requests its own Residential proxy automatically if you leave `proxyConfiguration` unset.
- Keyword matching requires **all** words in your keyword to appear somewhere in the job's title, company, description, or tags — use shorter, broader keywords if you're getting too few results.
- Raise `max_results` if you enable more sources, since results are pooled, filtered, and de-duplicated across all of them before the limit is applied.
- **Not currently supported:** large commercial boards like LinkedIn, Glassdoor, ZipRecruiter, Naukri, Totaljobs, Stepstone, and Jobstreet aren't included — most require paid partner/enterprise API access or run behind heavy anti-bot protection that can't be reliably or safely scraped. A custom integration can be added on request if you have a paid API contract with one of these providers.

***

### ❓ FAQ, Disclaimers, and Support

**Is this legal?** This Actor queries public APIs and RSS feeds by default (Remotive, RemoteOK, Arbeitnow, Jobicy, We Work Remotely, The Muse, Adzuna, USAJobs, Reed, Jooble). Every optional source beyond that — Indeed, Freelancer.com, Foundit, Bayt.com, Job Bank, jobs.ch, kariyer.net, Talent.com, OnlineJobs.ph, Glints, and CV-Library — either drives a headless browser or scrapes public pages rather than calling an official developer API, and each is disabled by default: enable them at your own discretion and review the target site's terms of use first. Talroo/Jobs2Careers uses its official, documented Search API under a Publisher account you apply for and agree to terms with directly.

**Why did a source return zero results?** Some sources (like Indeed) actively block automated requests and may intermittently return partial or no data — this is logged clearly in the run log and never stops the rest of the Actor from completing.

**Can I run this on a schedule or trigger it via API?** Yes — use Apify's built-in Scheduler, or call the Actor via the API/webhooks to integrate results into your own systems.

**Email**: bhavin.shah@techforceglobal.com

***

#### Need a Custom Pipeline?

Want more sources, scheduled refreshes, deeper enrichment, or a full data-warehouse integration?

#### [📅 Book a Free 15-min Consultation](https://calendly.com/techforce-infotech-pvt-ltd/intro-meeting?month=2026-01)

***

Made with ❤️ by **[Techforce](https://www.techforceglobal.com)**
Specialists in High-Performance Web Scrapers and AI Automation.

***

### Disclaimer

This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by any of the job boards it queries. All trademarks are property of their respective owners. The Actor collects only publicly available job listing data and does not log into, or scrape behind the authentication of, any platform. Use the data responsibly and in compliance with applicable laws (including GDPR/CCPA) and the terms of the platforms you operate on.

# Actor input Schema

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

Job title, skill, or company name to search for

## `location` (type: `string`):

City or region to focus results on. Leave blank for a broad/remote search.

## `country` (type: `string`):

Optional. Used by country-scoped sources (Adzuna, USAJobs) and as a location fallback for others. Leave blank for a broad, unrestricted search - each source falls back to its own sensible default (e.g. Adzuna defaults to the US, Bayt.com searches its whole international scope).

## `remote_only` (type: `boolean`):

Restrict results to remote-friendly positions only, where the source tells us that

## `job_type` (type: `string`):

Employment type to filter by

## `max_results` (type: `integer`):

Maximum number of jobs to return in total, across all selected sources

## `sources` (type: `array`):

Which job boards to scrape. All sources work out of the box using the Actor's built-in access - no setup needed. The fields below let you optionally use your own API keys for Adzuna, USAJobs, Reed, Jooble, Arbeitsagentur, or France Travail instead. Indeed, Arbeitsagentur, France Travail, VDAB, Freelancer.com, Foundit, Bayt.com, Job Bank, jobs.ch, kariyer.net, Talent.com, OnlineJobs.ph, Glints, and CV-Library are best-effort - see README. Talroo requires your own Publisher ID/Password (see the fields below) - it has no built-in fallback and returns nothing until those are set.

## `proxyConfiguration` (type: `object`):

Only used by the Indeed source, which is heavily rate-limited/blocked without a proxy. The other sources are plain public APIs and don't need one.

## `mcpConnector` (type: `string`):

Optionally deliver scraped jobs into a connector you have authorized - Notion, Slack, Airtable, Linear, or any MCP-compatible connector. Leave empty to only save results to the dataset.

## `deliveryMode` (type: `string`):

How to deliver to the connector: 'perJob' (one call per job listing - best for creating one Notion page/database row per job), 'chunked' (split the job list across a few calls so services like Notion never time out), 'summary' (one call with all jobs as a single text block), or 'none' (save to dataset only).

## `mcpTool` (type: `string`):

Name of the tool to call on the connector (e.g. 'notion-create-pages' for Notion, 'send\_message' for Slack, 'create\_issue' for Jira/GitHub). If unsure, run once with a connector selected - the log lists the connector's available tools, and once a valid tool name is set, also prints that tool's exact expected argument schema.

## `mcpArguments` (type: `object`):

Arguments passed to the connector tool. String values support {placeholders}. In 'perJob' mode: {title}, {company}, {location}, {url}, {source}, {jobType}, {remote}, {salary}, {description}, {postedDate}, {tags}, {keyword}, {jobCount}, and {message}. In 'summary'/'chunked' mode: {jobsText} (formatted job list, or one part of it in chunked mode), {keyword}, {jobCount}, and in chunked mode also {part}/{partCount}. IMPORTANT: this must match the tool's real argument shape exactly, or every call fails with an MCP 'Input validation error' (the dataset is unaffected - only delivery is skipped). After your first run, check the run log for 'Tool ... expects arguments shaped like:' followed by the connector's own full JSON Schema for the selected tool. For Notion's official 'notion-create-pages' tool (confirmed from its schema): the call takes a top-level "pages" ARRAY (max 100, required) plus an optional top-level "parent" object - {"page\_id": "..."}, {"database\_id": "..."}, or {"data\_source\_id": "..."} (omit entirely to create private workspace-level pages). Each item inside "pages" only accepts "properties" (a flat map of property name to string/number/array-of-strings/null - not the raw Notion API's nested rich\_text format), "content" (Markdown), "template\_id", "icon", and "cover" - a "parent" key inside a page item is rejected. Example (perJob mode, one call per job, creating a database page each time): {"parent": {"database\_id": "YOUR\_NOTION\_DATABASE\_ID"}, "pages": \[{"properties": {"Name": "{title}", "Company": "{company}", "Location": "{location}", "URL": "{url}", "Source": "{source}"}, "content": "{description}"}]}. Match the property names to your actual Notion database's columns.

## `mcpMessageTemplate` (type: `string`):

Optional template rendered and exposed as the {message} placeholder in the tool arguments. Per-job example: '{title} at {company} ({location}) - {url}'. Summary example: 'Found {jobCount} jobs for "{keyword}":\n\n{jobsText}'.

## Actor input object example

```json
{
  "keyword": "Data Engineer",
  "country": "",
  "remote_only": false,
  "job_type": "all",
  "max_results": 100,
  "sources": [
    "remotive",
    "remoteok",
    "arbeitnow",
    "jobicy",
    "weworkremotely",
    "themuse",
    "adzuna",
    "usajobs",
    "reed",
    "jooble"
  ],
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "deliveryMode": "none",
  "mcpTool": "",
  "mcpArguments": {},
  "mcpMessageTemplate": ""
}
```

# Actor output Schema

## `results` (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 = {
    "keyword": "Data Engineer"
};

// Run the Actor and wait for it to finish
const run = await client.actor("techforce.global/all-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 = { "keyword": "Data Engineer" }

# Run the Actor and wait for it to finish
run = client.actor("techforce.global/all-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 '{
  "keyword": "Data Engineer"
}' |
apify call techforce.global/all-jobs-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "All Jobs Scraper",
        "description": "All-in-one job scraper that aggregates 26+ job boards. Indeed, Adzuna, USAJobs, Reed, Remotive, and more into one de-duplicated feed by keyword. Get title, company, salary, location, remote status, and posting date, ready for JSON, CSV, Excel, or API/webhook delivery into Notion, Slack, or Airtable.",
        "version": "0.1",
        "x-build-id": "9urWjrRkplV6bHsfI"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/techforce.global~all-jobs-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-techforce.global-all-jobs-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/techforce.global~all-jobs-scraper/runs": {
            "post": {
                "operationId": "runs-sync-techforce.global-all-jobs-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/techforce.global~all-jobs-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-techforce.global-all-jobs-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "keyword"
                ],
                "properties": {
                    "keyword": {
                        "title": "Keyword",
                        "type": "string",
                        "description": "Job title, skill, or company name to search for"
                    },
                    "location": {
                        "title": "Location",
                        "type": "string",
                        "description": "City or region to focus results on. Leave blank for a broad/remote search."
                    },
                    "country": {
                        "title": "Country",
                        "enum": [
                            "",
                            "Algeria",
                            "Angola",
                            "Argentina",
                            "Australia",
                            "Austria",
                            "Azerbaijan",
                            "Bahrain",
                            "Bangladesh",
                            "Belgium",
                            "Bosnia and Herzegovina",
                            "Brazil",
                            "Bulgaria",
                            "Cameroon",
                            "Canada",
                            "Chile",
                            "China",
                            "Colombia",
                            "Costa Rica",
                            "Croatia",
                            "Cyprus",
                            "Czechia",
                            "Denmark",
                            "Dominican Republic",
                            "Ecuador",
                            "Egypt",
                            "El Salvador",
                            "Estonia",
                            "Finland",
                            "France",
                            "Germany",
                            "Ghana",
                            "Greece",
                            "Guatemala",
                            "Hong Kong",
                            "Hungary",
                            "India",
                            "Indonesia",
                            "Iraq",
                            "Ireland",
                            "Israel",
                            "Italy",
                            "Ivory Coast",
                            "Japan",
                            "Jordan",
                            "Kazakhstan",
                            "Kenya",
                            "Kuwait",
                            "Latvia",
                            "Lebanon",
                            "Libya",
                            "Lithuania",
                            "Luxembourg",
                            "Malaysia",
                            "Malta",
                            "Mexico",
                            "Morocco",
                            "Mozambique",
                            "Netherlands",
                            "New Zealand",
                            "Nigeria",
                            "Norway",
                            "Oman",
                            "Pakistan",
                            "Panama",
                            "Peru",
                            "Philippines",
                            "Poland",
                            "Portugal",
                            "Puerto Rico",
                            "Qatar",
                            "Romania",
                            "Russia",
                            "Saudi Arabia",
                            "Senegal",
                            "Serbia",
                            "Singapore",
                            "Slovakia",
                            "Slovenia",
                            "South Africa",
                            "South Korea",
                            "Spain",
                            "Sweden",
                            "Switzerland",
                            "Taiwan",
                            "Thailand",
                            "Tunisia",
                            "Turkey",
                            "Uganda",
                            "Ukraine",
                            "United Arab Emirates",
                            "United Kingdom",
                            "United States",
                            "Uruguay",
                            "Uzbekistan",
                            "Venezuela",
                            "Vietnam",
                            "Yemen",
                            "Zambia"
                        ],
                        "type": "string",
                        "description": "Optional. Used by country-scoped sources (Adzuna, USAJobs) and as a location fallback for others. Leave blank for a broad, unrestricted search - each source falls back to its own sensible default (e.g. Adzuna defaults to the US, Bayt.com searches its whole international scope).",
                        "default": ""
                    },
                    "remote_only": {
                        "title": "Remote only",
                        "type": "boolean",
                        "description": "Restrict results to remote-friendly positions only, where the source tells us that",
                        "default": false
                    },
                    "job_type": {
                        "title": "Job type",
                        "enum": [
                            "all",
                            "fulltime",
                            "parttime",
                            "contract",
                            "internship"
                        ],
                        "type": "string",
                        "description": "Employment type to filter by",
                        "default": "all"
                    },
                    "max_results": {
                        "title": "Max results",
                        "minimum": 10,
                        "maximum": 5000,
                        "type": "integer",
                        "description": "Maximum number of jobs to return in total, across all selected sources",
                        "default": 100
                    },
                    "sources": {
                        "title": "Sources",
                        "type": "array",
                        "description": "Which job boards to scrape. All sources work out of the box using the Actor's built-in access - no setup needed. The fields below let you optionally use your own API keys for Adzuna, USAJobs, Reed, Jooble, Arbeitsagentur, or France Travail instead. Indeed, Arbeitsagentur, France Travail, VDAB, Freelancer.com, Foundit, Bayt.com, Job Bank, jobs.ch, kariyer.net, Talent.com, OnlineJobs.ph, Glints, and CV-Library are best-effort - see README. Talroo requires your own Publisher ID/Password (see the fields below) - it has no built-in fallback and returns nothing until those are set.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "remotive",
                                "remoteok",
                                "arbeitnow",
                                "jobicy",
                                "weworkremotely",
                                "themuse",
                                "adzuna",
                                "usajobs",
                                "arbetsformedlingen",
                                "reed",
                                "jooble",
                                "france_travail",
                                "indeed",
                                "freelancer",
                                "foundit",
                                "jobbank",
                                "jobs_ch",
                                "kariyer",
                                "talent_com",
                                "onlinejobsph",
                                "glints"
                            ],
                            "enumTitles": [
                                "Remotive",
                                "RemoteOK",
                                "Arbeitnow",
                                "Jobicy",
                                "We Work Remotely",
                                "The Muse",
                                "Adzuna",
                                "USAJobs (US gov jobs only)",
                                "Arbetsformedlingen (Sweden)",
                                "Reed.co.uk (UK jobs only)",
                                "Jooble",
                                "France Travail (France)",
                                "Indeed (needs proxy)",
                                "Freelancer.com",
                                "Foundit (India only)",
                                "Job Bank (Canada only)",
                                "jobs.ch (Switzerland only)",
                                "kariyer.net (Turkey only)",
                                "Talent.com",
                                "OnlineJobs.ph (Philippines only)",
                                "Glints (Southeast Asia only)"
                            ]
                        },
                        "default": [
                            "remotive",
                            "remoteok",
                            "arbeitnow",
                            "jobicy",
                            "weworkremotely",
                            "themuse",
                            "adzuna",
                            "usajobs",
                            "reed",
                            "jooble"
                        ]
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Only used by the Indeed source, which is heavily rate-limited/blocked without a proxy. The other sources are plain public APIs and don't need one.",
                        "default": {
                            "useApifyProxy": false
                        }
                    },
                    "mcpConnector": {
                        "title": "Deliver to (MCP connector)",
                        "type": "string",
                        "description": "Optionally deliver scraped jobs into a connector you have authorized - Notion, Slack, Airtable, Linear, or any MCP-compatible connector. Leave empty to only save results to the dataset."
                    },
                    "deliveryMode": {
                        "title": "Delivery mode",
                        "enum": [
                            "perJob",
                            "chunked",
                            "summary",
                            "none"
                        ],
                        "type": "string",
                        "description": "How to deliver to the connector: 'perJob' (one call per job listing - best for creating one Notion page/database row per job), 'chunked' (split the job list across a few calls so services like Notion never time out), 'summary' (one call with all jobs as a single text block), or 'none' (save to dataset only).",
                        "default": "none"
                    },
                    "mcpTool": {
                        "title": "Connector tool name",
                        "type": "string",
                        "description": "Name of the tool to call on the connector (e.g. 'notion-create-pages' for Notion, 'send_message' for Slack, 'create_issue' for Jira/GitHub). If unsure, run once with a connector selected - the log lists the connector's available tools, and once a valid tool name is set, also prints that tool's exact expected argument schema.",
                        "default": ""
                    },
                    "mcpArguments": {
                        "title": "Connector tool arguments",
                        "type": "object",
                        "description": "Arguments passed to the connector tool. String values support {placeholders}. In 'perJob' mode: {title}, {company}, {location}, {url}, {source}, {jobType}, {remote}, {salary}, {description}, {postedDate}, {tags}, {keyword}, {jobCount}, and {message}. In 'summary'/'chunked' mode: {jobsText} (formatted job list, or one part of it in chunked mode), {keyword}, {jobCount}, and in chunked mode also {part}/{partCount}. IMPORTANT: this must match the tool's real argument shape exactly, or every call fails with an MCP 'Input validation error' (the dataset is unaffected - only delivery is skipped). After your first run, check the run log for 'Tool ... expects arguments shaped like:' followed by the connector's own full JSON Schema for the selected tool. For Notion's official 'notion-create-pages' tool (confirmed from its schema): the call takes a top-level \"pages\" ARRAY (max 100, required) plus an optional top-level \"parent\" object - {\"page_id\": \"...\"}, {\"database_id\": \"...\"}, or {\"data_source_id\": \"...\"} (omit entirely to create private workspace-level pages). Each item inside \"pages\" only accepts \"properties\" (a flat map of property name to string/number/array-of-strings/null - not the raw Notion API's nested rich_text format), \"content\" (Markdown), \"template_id\", \"icon\", and \"cover\" - a \"parent\" key inside a page item is rejected. Example (perJob mode, one call per job, creating a database page each time): {\"parent\": {\"database_id\": \"YOUR_NOTION_DATABASE_ID\"}, \"pages\": [{\"properties\": {\"Name\": \"{title}\", \"Company\": \"{company}\", \"Location\": \"{location}\", \"URL\": \"{url}\", \"Source\": \"{source}\"}, \"content\": \"{description}\"}]}. Match the property names to your actual Notion database's columns.",
                        "default": {}
                    },
                    "mcpMessageTemplate": {
                        "title": "Message template",
                        "type": "string",
                        "description": "Optional template rendered and exposed as the {message} placeholder in the tool arguments. Per-job example: '{title} at {company} ({location}) - {url}'. Summary example: 'Found {jobCount} jobs for \"{keyword}\":\\n\\n{jobsText}'.",
                        "default": ""
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
