# Remote Jobs Scraper: Remote OK, We Work Remotely, Jobicy (`joesimo/remote-jobs`) Actor

Remote jobs from Remote OK, We Work Remotely and Jobicy in one deduplicated dataset: title, company, location, salary as numbers, tags, posted date, description and job link. Filter by keyword, location, salary and days. Official public feeds, no login.

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

## Pricing

$1.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

## Remote Jobs Scraper: Remote OK, We Work Remotely and Jobicy in one dataset

**Get the current remote jobs from three of the biggest remote job boards as one clean, deduplicated list:** title, company, where the job can be done, salary as numbers (min, max, currency, period), tags, category, job type, posted date, plain-text description and the link to the job. Filter by keywords, location, minimum salary and days since posting. The Actor reads only the boards' own public feeds (the Remote OK API, the We Work Remotely RSS feeds and the Jobicy API), so there is no login, no browser and no proxy.

- **$1.00 per 1,000 jobs.** A board that cannot be read and a search with no matches come back as free status rows.
- **One row per job across boards:** when a company posts the same title on two boards, you get one row with the other link in `alsoListedOn`, and salary or location missing on one board is filled from the other.
- **Salary as numbers:** 21 of the 50 jobs in the default run had `salaryMin` and `salaryMax`. With `minSalary` set, every saved job has one.
- **Small and fast:** 256 MB, plain HTTP. The default run took 3 seconds in the Apify cloud.

### Quick start

1. Click **Try for free** and press **Start** with the empty form.
2. Or call the API with an empty input `{}`.

Both return the 50 newest jobs, with the three boards taking turns (Jobicy, We Work Remotely, Remote OK, then again). On Nov 3, 2026 this run took 3 seconds and saved 50 jobs (17 Jobicy, 17 We Work Remotely, 16 Remote OK) and merged 9 cross-board duplicates, so it costs 50 x $0.001 = $0.05. One of the 50 rows (description shortened):

```json
{
    "status": "ok",
    "source": "weworkremotely",
    "sourceName": "We Work Remotely",
    "id": "weworkremotely:crowdstrike-regional-principal-analyst-falcon-complete-remote",
    "url": "https://weworkremotely.com/remote-jobs/crowdstrike-regional-principal-analyst-falcon-complete-remote",
    "title": "Regional Principal Analyst, Falcon Complete (Remote)",
    "company": "CrowdStrike",
    "companyLogo": null,
    "location": "USA Only",
    "isWorldwide": false,
    "headquarters": null,
    "categories": ["Full-Stack Programming"],
    "tags": ["Bash", "Python", "Quality Assurance"],
    "employmentType": "Full-Time",
    "seniority": null,
    "salaryMin": 145000,
    "salaryMax": 220000,
    "salaryCurrency": "USD",
    "salaryPeriod": "year",
    "salaryText": "$145,000 - $220,000",
    "postedAt": "2026-11-02T17:00:19.000Z",
    "expiresAt": "2026-12-02T17:00:14.000Z",
    "descriptionText": "Headquarters: Missouri, United States\n\nURL: http://www.crowdstrike.com\n\nAs a global leader in cybersecurity, CrowdStrike protects the people, processes and tech ...",
    "alsoListedOn": [],
    "postedDaysAgo": 0,
    "scrapedAt": "2026-11-03T13:33:01.156Z"
}
```

A search for engineering jobs with a salary of at least 80,000 a year, open in the USA or Europe and posted in the last 7 days (example 1 below) saved 143 jobs in 19 seconds on the same day: 128 from Jobicy and 15 from We Work Remotely, all 143 with a salary, 102 of them listed as "USA". It read 626 We Work Remotely jobs from 12 feeds and 1,293 Jobicy jobs from 13 pages, and the platform cost of the run was $0.0004.

### What you get per job

| Field | What it holds |
|---|---|
| `title`, `company`, `companyLogo` | The job title, company name and logo URL |
| `location`, `isWorldwide` | Where the job can be done as the board writes it (USA Only, Anywhere in the World, Germany, EMEA), and `true` when it is open worldwide |
| `salaryMin`, `salaryMax`, `salaryCurrency`, `salaryPeriod` | Salary as numbers. From the board's own fields, or read from the description (`salaryText` then shows the text it came from) |
| `categories`, `tags`, `employmentType`, `seniority` | Board category or industry, skills, Full-Time or Contract, and level where the board has it |
| `postedAt`, `postedDaysAgo`, `expiresAt` | Posting time in UTC, days since posting, and expiry where the board has it |
| `descriptionText` | The full description as plain text (`descriptionHtml` too with `includeDescriptionHtml`) |
| `url`, `source`, `sourceName`, `alsoListedOn` | The job page on the board, which board it came from, and the same job on other boards |

### Pricing

| Event | Price | When |
|---|---|---|
| Job | $0.001 ($1.00 per 1,000) | One job saved with status `ok` |

Cost examples: the default run of 50 jobs costs $0.05. A daily alert for one search that finds 30 new jobs a day costs $0.90 a month. Every current job on all three boards, about 2,000 rows, costs about $2.00. Apify platform usage is included in the price. Rows with status `no_jobs`, `failed` or `blocked_by_robots` are free. The run stops at the maximum cost per run you set.

### Use cases

- **Remote job alerts:** schedule a daily run with `postedWithinDays: 1` and your keywords, and send new rows to email, Slack or a sheet through an Apify integration.
- **Job boards and newsletters:** a daily feed of remote jobs from three boards with duplicates merged. Link each job to its `url` on the source board.
- **Salary research:** remote salary ranges by title, skill and region as numbers you can sort and average.
- **Recruiting and sales intelligence:** which companies hire remotely right now, for which roles, and how often they post.
- **Career tools and AI agents:** a clean JSON list of remote jobs to match against a resume.

### Example inputs

Copy one of these into the **JSON** tab of the input form.

**1. Engineering jobs open in the USA or Europe, salary at least 80,000 a year, posted in the last 7 days.**

```json
{
    "keywords": ["engineer", "developer", "python", "react"],
    "locations": ["USA", "Europe"],
    "postedWithinDays": 7,
    "minSalary": 80000,
    "maxItems": 300
}
```

**2. Designer jobs from We Work Remotely and Jobicy, without descriptions.** On Nov 3, 2026 this saved 29 jobs in 8 seconds.

```json
{
    "keywords": ["designer"],
    "sources": ["weworkremotely", "jobicy"],
    "includeDescription": false,
    "maxItems": 40
}
```

**3. Today's customer support jobs anywhere in the world.**

```json
{
    "keywords": ["customer support", "customer success", "support"],
    "excludeKeywords": ["senior", "manager"],
    "postedWithinDays": 1,
    "maxItems": 100
}
```

### How the filters work

- **Keywords:** a job is kept when at least one keyword appears as a whole word in its title, company, tags or category, in any case. `java` does not match JavaScript. Turn on `searchInDescription` to search the description too.
- **Locations:** matched against the board's location text. `USA` also matches "United States", "North America" and the 50 US state names. `UK` matches "United Kingdom" and "Europe", `Europe` matches "EU" and "EMEA". Jobs open worldwide are kept too (turn off `includeWorldwide` to drop them). Remote OK often lists no location; turn on `includeUnknownLocation` to keep those.
- **Salary:** `minSalary` compares the top of the range per year in the job's own currency (hourly x 2080, monthly x 12). Jobs without a salary are dropped when it is set.
- **Order:** the boards take turns, each newest first, so a small `maxItems` still has jobs from every board.

### Sources and fair use

| Board | How it is read | Requests per run |
|---|---|---|
| [Remote OK](https://remoteok.com) | Public JSON API at remoteok.com/api, the newest 100 jobs | 1 |
| [We Work Remotely](https://weworkremotely.com) | Public RSS feeds: the main feed (newest 100) and 11 category feeds when more jobs are needed | 1 to 12 |
| [Jobicy](https://jobicy.com) | Public jobs API at jobicy.com/api/jobs, about 7 days of jobs, 100 per page | 1 to 20 |

The Actor checks each board's robots.txt before reading it and makes at most about 33 requests per run. Remote OK's API terms ask that you name Remote OK as the source and link back to the job URL on Remote OK, and Jobicy asks for credit with a link to the listing. Each row has `sourceName` and `url` for that. The rows hold job ads only: no applicant data and no personal emails or phone numbers.

### Run summary

Each run writes an `OUTPUT` record to its key-value store with jobs saved per board, duplicates merged, jobs read and matched per board, requests, download size and the stop reason.

### FAQ

**How fresh are the jobs?** Each run reads the boards' feeds live, so a job shows up as soon as the board puts it in its feed. Jobicy's API covers about the last 7 days.

**Why do I get fewer jobs than maxItems?** The three boards together hold about 2,000 current jobs, and filters narrow that down. The run summary shows how many jobs each board had and how many matched.

**Can I get jobs from other boards?** For company career sites use [Workday Jobs Scraper](https://apify.com/joesimo/workday-jobs) or [Multi ATS Jobs Scraper](https://apify.com/joesimo/multi-ats-jobs) (Greenhouse, Lever, Ashby and more).

**Something is wrong or missing?** Open an issue on the Actor's Issues tab with the run link and it will be looked at.

# Actor input Schema

## `keywords` (type: `array`):

Job must contain at least one of these words in its title, company, tags or category (whole words, any case), for example python, react, designer, customer support. Leave empty for all remote jobs.

## `locations` (type: `array`):

Where the job can be done, matched to the board's location text: countries, regions or US states (USA, UK, Europe, Canada, LATAM, Germany, Texas). USA also matches US state names. Several values are combined with OR. Leave empty for any location.

## `includeWorldwide` (type: `boolean`):

With Locations set, also keep jobs open anywhere in the world.

## `includeUnknownLocation` (type: `boolean`):

With Locations set, also keep jobs whose board lists no location (common on Remote OK).

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

Only jobs posted in the last N days. 0 means no limit (the boards keep jobs from the last few days to about a month).

## `minSalary` (type: `integer`):

Only jobs whose top salary is at least this much per year, in the job's own currency (hourly x 2080, monthly x 12). Jobs without a salary are dropped when this is set. 0 means no limit.

## `onlyWithSalary` (type: `boolean`):

Keep only jobs that state a salary or salary range.

## `excludeKeywords` (type: `array`):

Drop jobs whose title or company contains any of these words, for example senior, intern, crypto.

## `searchInDescription` (type: `boolean`):

Match Keywords in the full job description too. Finds more jobs, with more loose matches.

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

Boards to read. All three by default.

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

Stop after this many jobs. Each job is one charged result. The three boards together hold about 2,000 current jobs.

## `dedupe` (type: `boolean`):

Keep one row when the same company posts the same title on more than one board. The other links go into alsoListedOn.

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

Full job description as plain text in descriptionText.

## `includeDescriptionHtml` (type: `boolean`):

Also save the original description HTML in descriptionHtml (bigger rows).

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

Not needed: the boards serve their public feeds without a proxy. Use only if a board blocks your runs.

## Actor input object example

```json
{
  "keywords": [],
  "locations": [],
  "includeWorldwide": true,
  "includeUnknownLocation": false,
  "postedWithinDays": 0,
  "minSalary": 0,
  "onlyWithSalary": false,
  "excludeKeywords": [],
  "searchInDescription": false,
  "sources": [
    "remoteok",
    "weworkremotely",
    "jobicy"
  ],
  "maxItems": 50,
  "dedupe": true,
  "includeDescription": true,
  "includeDescriptionHtml": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

One item per job, plus free status rows for a board that failed or a run with no matches.

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

JSON summary: jobs saved per board, duplicates merged, jobs read per board, requests and stop reason.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("joesimo/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 = {}

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

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,joesimo/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/Em4AyVUKVp7aT9L3j/builds/ZWcyoNMwO88ETIskG/openapi.json
