# Remote Jobs Scraper: RemoteOK and Himalayas (`bepolabs/remote-jobs`) Actor

Also covers Jobicy and Arbeitnow, drops duplicates and turns pay text into numbers. Costs 1 USD per 1,000 postings.

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

## Pricing

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

### 🌍 What is Remote Jobs?

Reads the public feeds of RemoteOK, Himalayas and two more boards and returns one deduplicated dataset of remote jobs, with duplicate listings merged (JSON, CSV or Excel), no key needed, with identical fields for every opening: title, company, location, salary, posted date and apply link. Narrow it by keyword, region and age; each row credits its origin, as their terms ask. The schema matches our ATS Jobs Actor, so both combine.

- **Boards and newsletters**: fill a niche listing site or a weekly email from four sources at once
- **Job search**: get every new remote Python, design or marketing opening in one sheet instead of four tabs
- **Recruiting and sales leads**: see which companies hire remotely right now, and for which roles
- **Pay research**: collect advertised salary ranges by role, parsed into numbers
- **Alerts**: schedule a daily run with `postedWithinDays: 1` and send new jobs to Slack or email

![Remote Jobs: Remote jobs from Remote OK, Himalayas, Jobicy and Arbeitnow in one deduped feed, with salary, posted date and apply link.](https://api.apify.com/v2/key-value-stores/wdeAWGooHdIhvFgSY/records/remote-jobs-hero.png)

#### ✨ Why use this Actor?

- ✅ **Four boards, one schema**: Remote OK, Himalayas, Jobicy and Arbeitnow mapped to the same fields
- ✅ **No duplicates**: the same job on two boards (same company and title, or same apply URL) counts once
- ✅ **Pay as numbers**: salary text such as "120,000" or "211.4K" becomes `salaryMin`, `salaryMax`, currency and period
- ✅ **Attribution built in**: every row carries `source`, `sourceUrl` and an `attribution` line, as the boards' terms ask
- ✅ **A failed board does not stop the run**: each feed is retried with backoff; failures are reported and not charged
- ✅ **Cheap**: 1 USD per 1,000 jobs, nothing per run

### 📦 What data can you get with Remote Jobs?

| | | |
|---|---|---|
| 💼 Job title | 🏢 Company | 📍 Location |
| 🏠 Remote flag | 🏷️ Department, categories or tags | 💰 Salary min and max, currency, period |
| 📅 Posted date (ISO) | 🔗 Apply URL and job URL | 🆔 Job ID |
| 📡 Source board, source URL and attribution |  |  |

### 🚀 How to use Remote Jobs

Remote Jobs works in a few clicks, no coding needed:

1. [Create a free Apify account](https://console.apify.com/sign-up) (the free plan includes 5 USD of monthly credit).
2. Open [Remote Jobs](https://apify.com/bepolabs/remote-jobs) and click **Try for free**.
3. Enter a keyword such as engineer or product manager, optionally a location and an age limit, and pick the boards.
4. Click **Start** and wait for the run to finish (most runs take seconds).
5. Download your data as JSON, CSV, Excel, XML or HTML, or send it straight to Google Sheets, Make, Zapier or your AI agent.

![How Remote Jobs works](https://api.apify.com/v2/key-value-stores/wdeAWGooHdIhvFgSY/records/remote-jobs-workflow.png)

### ⬇️ Input

Everything is optional: an empty input returns the latest remote jobs of all four boards, up to 200 per board.

##### Keyword

Every word must appear in the title, category or company. `product manager` keeps jobs containing both.

##### Location

Text matched in the job's location, such as `USA`, `Germany` or `Europe`. Jobs marked Worldwide or Anywhere are always kept.

##### Remote only

On by default. Arbeitnow also lists on-site jobs in Germany; switch `remoteOnly` off to keep them.

##### How many jobs

Remote OK returns its latest ~100 jobs and Jobicy the last 7 days; Himalayas and Arbeitnow page further. `maxJobsPerSource` caps each board after the filters.

| Field | Type | What it does | Default |
|---|---|---|---|
| **Keyword** (`keyword`) | string | Keep jobs whose title, category or company contains all these words, e.g. | `"engineer"` |
| **Sources** (`sources`) | array | Job boards to read. | `["remoteok","himalayas","jobicy","arbeit` |
| **Location** (`location`) | string | Keep jobs open to this place (text in the location, e.g. |  |
| **Remote only** (`remoteOnly`) | boolean | Keep only remote jobs (Arbeitnow also lists on-site jobs in Germany). | `true` |
| **Posted within days** (`postedWithinDays`) | integer | Keep jobs posted in the last N days. | `30` |
| **Maximum jobs per source** (`maxJobsPerSource`) | integer | Cap per source after the filters. | `200` |
| **Maximum retries** (`maxRetries`) | integer | Retries per request with exponential backoff. | `4` |

![Remote Jobs input form](https://api.apify.com/v2/key-value-stores/wdeAWGooHdIhvFgSY/records/remote-jobs-input.png)

#### Input example

```json
{
    "keyword": "engineer",
    "maxJobsPerSource": 30
}
```

### ⬆️ Output

Every posting becomes one row with identical fields, whatever its origin. The run summary (`OUTPUT` in the key-value store) lists each board with the number found and kept, plus the error if one failed.

![Remote Jobs output table](https://api.apify.com/v2/key-value-stores/wdeAWGooHdIhvFgSY/records/remote-jobs-output.png)

#### Output example

One row of the dataset (keyword engineer, a Himalayas job with salary):

```json
{
    "title": "Senior Dam Safety Engineer",
    "company": "Schnabel Engineering",
    "location": "United States",
    "remote": true,
    "department": null,
    "salaryMin": 180000,
    "salaryMax": 215000,
    "salaryCurrency": "USD",
    "salaryPeriod": "year",
    "postedAt": "2026-10-10T16:58:13.000Z",
    "applyUrl": "https://himalayas.app/companies/schnabel-engineering/jobs/senior-dam-safety-engineer",
    "jobUrl": "https://himalayas.app/companies/schnabel-engineering/jobs/senior-dam-safety-engineer",
    "sourceAts": "himalayas",
    "board": "Himalayas",
    "jobId": "https://himalayas.app/companies/schnabel-engineering/jobs/senior-dam-safety-engineer",
    "source": "Himalayas",
    "sourceUrl": "https://himalayas.app/companies/schnabel-engineering/jobs/senior-dam-safety-engineer",
    "attribution": "Job via Himalayas (https://himalayas.app)"
}
```

#### Sources and their terms (read 2026-10-14)

Every board asks for two things: a link to the posting and its name as the source. Each row carries both; **when you republish these jobs, include `attribution` and `sourceUrl`**.

| Source | API | Terms at the source |
|---|---|---|
| Remote OK | `remoteok.com/api` (latest ~100) | Notice in the API: link back with a followed link, name Remote OK as the source; no Remote OK logo without written permission (this Actor returns no logos). |
| Himalayas | `himalayas.app/jobs/api` and `/jobs/api/search` | himalayas.app/api: link back and name Himalayas; do not submit its jobs to third-party job sites (Jooble, Neuvoo, Google Jobs, LinkedIn Jobs). |
| Jobicy | `jobicy.com/api/v2/remote-jobs` (last 7 days) | Credit Jobicy with a direct link; apply buttons go to the job URL in the feed. |
| Arbeitnow | `arbeitnow.com/api/job-board-api` | Terms section 11: link back to Arbeitnow.com; permission can be revoked. |

View the results as a table or JSON in the Output tab and download them as JSON, CSV, Excel, XML, HTML or RSS, all fields or only those you pick.

### 💰 How much does Remote Jobs cost?

Remote Jobs is priced **per event**: **1 USD per 1,000 jobs** (0.001 USD per job), with no monthly rental. Each saved row is one charge; boards that fail cost nothing.

| You get | You pay |
|---|---|
| 100 jobs | 0.1 USD |
| 1,000 jobs | 1 USD |
| 10,000 jobs | 10 USD |
| 100,000 jobs | 100 USD |

💡 Apify's free plan gives you 5 USD of credit every month, enough for about **5,000 jobs** at no cost. Set a spending limit per run and the Actor stops there.

### ⚖️ Remote Jobs vs. the alternatives

| | Remote Jobs | Single-board scrapers | Browsing the boards |
|---|---|---|---|
| **Four boards in one run** | ✅ | ❌ one each | 4 tabs |
| **Duplicates removed across boards** | ✅ | ❌ | ❌ |
| **Salary parsed into numbers** | ✅ | varies | ❌ |
| **Source and attribution per row** | ✅ | rarely | – |
| **Schedules, API and MCP** | ✅ | ✅ | ❌ |

### 🔌 Integrations, API and MCP

#### Connect Remote Jobs to your AI agent (MCP)

Give Claude, ChatGPT, Cursor or any MCP client direct access to Remote Jobs through the [Apify MCP server](https://mcp.apify.com). Add this URL to its settings:

```text
https://mcp.apify.com/?actors=bepolabs/remote-jobs
```

For Claude Desktop, add it under `mcpServers` in `claude_desktop_config.json`:

```json
{
    "mcpServers": {
        "remote-jobs": {
            "command": "npx",
            "args": [
                "-y",
                "@apify/actors-mcp-server",
                "--actors",
                "bepolabs/remote-jobs"
            ],
            "env": {
                "APIFY_TOKEN": "<your Apify API token>"
            }
        }
    }
}
```

Then ask: *"Find remote engineering jobs posted in the last 3 days that are open to Europe, and list title, company and apply link."*

#### Run it from your code

Python (`pip install apify-client`):

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("bepolabs/remote-jobs").call(run_input={"keyword":"engineer","maxJobsPerSource":30})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

JavaScript (`npm install apify-client`):

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('bepolabs/remote-jobs').call({"keyword":"engineer","maxJobsPerSource":30});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### No-code integrations

Send results to **Google Sheets, Slack, Airtable, HubSpot, Make, Zapier, n8n** and more from the Integrations tab, start runs on a **schedule**, or trigger your own endpoint with a **webhook** when a run finishes. The [Apify API](https://docs.apify.com/api/v2) gives you full control over runs and datasets.

### ❓ FAQ

##### Which job boards are included?

Remote OK, Himalayas, Jobicy and Arbeitnow, through their public job APIs. Remotive is left out on purpose: its terms forbid passing its jobs to third-party sites.

##### How are duplicates found?

Two jobs with the same apply URL, or the same company and title, count once; the first board in your `sources` list wins.

##### Do all jobs have a salary?

No, only where the board gives one. When it does, the text is parsed into `salaryMin`, `salaryMax`, `salaryCurrency` and `salaryPeriod`.

##### How do I get only new jobs?

Use `postedWithinDays` (for example 1) and schedule the Actor daily.

##### Can I combine these rows with company career pages?

Yes. The rows share the schema of our ATS Jobs Actor, so they merge with postings from Greenhouse, Lever, Ashby and other career pages.

##### Can I filter by company size or get only some boards?

Pick boards in `sources`. Size is not offered: none of the four publishes it, so filter by `keyword` (it also matches the company name) or join the rows with your own list.

##### Is it legal to use Remote Jobs?

The Actor reads only the public feeds the four providers offer for reuse, and every row carries the name and URL they ask for. If you republish listings, show `attribution`, link `sourceUrl` and follow each board's terms in the table above (for example, Himalayas postings may not be submitted to other job sites).

##### What if something is missing or does not work?

Open an issue on the **Issues** tab; we read each one and reply. Feature requests are welcome too.

### 💬 Your feedback

Tell us what Remote Jobs should add on the **Issues** tab or leave a review; your notes decide what we work on next.

### 🔗 Related Actors

| Actor | What it does |
|---|---|
| 💼 [ATS Jobs](https://apify.com/bepolabs/ats-jobs) | Every open job from company career boards on Greenhouse, Lever, Ashby, Workable, SmartRecruiters and Recruitee in one deduped feed. |
| 📊 [Google Sheets Import and Export](https://apify.com/bepolabs/google-sheets) | Send any Apify dataset or JSON to a Google Sheet (append, replace or upsert by key), or read a sheet back as clean rows. |
| 🌐 [Domain RDAP and DNS](https://apify.com/bepolabs/domain-rdap) | Domains to registrar, creation and expiry dates, age, status, nameservers, DNSSEC and DNS records from official RDAP, in bulk. |
| 🟧 [Hacker News Search](https://apify.com/bepolabs/hacker-news) | Hacker News stories, comments, Ask HN, Show HN and jobs for any search, with points, comment count, date and text. |
| 🩺 [NPI Registry Lookup](https://apify.com/bepolabs/npi-registry) | US doctors, nurses, clinics and pharmacies from the official CMS NPI Registry, by specialty, name, NPI or place. |
| 📍 [OpenStreetMap Places](https://apify.com/bepolabs/osm-pois) | Shops, restaurants and offices in any city or area, with address, phone, website, opening hours and coordinates. |
| 📞 [Phone Number Validator](https://apify.com/bepolabs/phone-validator) | Bulk phone number validation offline: valid or not, E.164 format, country and line type (mobile, fixed line, VoIP) for every number. |
| 🏛️ [SAM.gov Contract Opportunities](https://apify.com/bepolabs/sam-gov) | US federal contract opportunities by keyword, NAICS, set-aside or agency, with deadlines, contacts and attachments. |

# Changelog

This Actor's version history is a separate document: https://apify.com/bepolabs/remote-jobs/changelog.md

# Actor input Schema

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

Keep jobs whose title, category or company contains all these words, e.g. python or product manager. Empty: all jobs.

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

Job boards to read. Default: all four.

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

Keep jobs open to this place (text in the location, e.g. USA or Europe); jobs marked Worldwide or Anywhere always match.

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

Keep only remote jobs (Arbeitnow also lists on-site jobs in Germany).

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

Keep jobs posted in the last N days. Empty: no age limit.

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

Cap per source after the filters.

## `maxRetries` (type: `integer`):

Retries per request with exponential backoff.

## Actor input object example

```json
{
  "keyword": "engineer",
  "sources": [
    "remoteok",
    "himalayas",
    "jobicy",
    "arbeitnow"
  ],
  "remoteOnly": true,
  "postedWithinDays": 30,
  "maxJobsPerSource": 200,
  "maxRetries": 4
}
```

# Actor output Schema

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

Dataset items, one row per result, in the overview table view.

# 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": "engineer",
    "postedWithinDays": 30
};

// Run the Actor and wait for it to finish
const run = await client.actor("bepolabs/remote-jobs").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": "engineer",
    "postedWithinDays": 30,
}

# Run the Actor and wait for it to finish
run = client.actor("bepolabs/remote-jobs").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 '{
  "keyword": "engineer",
  "postedWithinDays": 30
}' |
apify call bepolabs/remote-jobs --silent --output-dataset

```

## MCP server setup

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

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/sgIYTsEudhGWyQQv1/builds/6cwsLbAag4ydG3VrT/openapi.json
