Remote Job Aggregator — RemoteOK, WeWorkRemotely + 8 Boards avatar

Remote Job Aggregator — RemoteOK, WeWorkRemotely + 8 Boards

Pricing

from $2.00 / 1,000 job results

Go to Apify Store
Remote Job Aggregator — RemoteOK, WeWorkRemotely + 8 Boards

Remote Job Aggregator — RemoteOK, WeWorkRemotely + 8 Boards

Remote job aggregator sweeping 10 keyless boards in one run - RemoteOK, WeWorkRemotely, Working Nomads, Remotive, Jobicy, Himalayas, DevITjobs (US + UK), The Muse and HN Who is Hiring - deduplicated across boards, salaries annualized. The same role on two boards ships once.

Pricing

from $2.00 / 1,000 job results

Rating

0.0

(0)

Developer

Flash Scrape

Flash Scrape

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 hours ago

Last modified

Categories

Share

A remote job aggregator that sweeps ten keyless remote job boards in one run — RemoteOK, WeWorkRemotely, Working Nomads, DevITjobs (US + UK, remote rows only), The Muse (remote filter), Remotive, Jobicy, Himalayas and the Hacker News "Who is hiring?" thread — and returns one clean, deduplicated dataset.

Every posting is normalized to the same schema (title, company, location, salary where the board publishes one, posting date, tags, description snippet, direct link), and the same role listed on two boards ships once: rows are merged across boards by canonical job URL and by (title, company). That cross-board deduplication is what a single-board scraper can't give you — you pay per unique job, not per feed it happened to appear in.

Three things no other multi-board remote actor offers:

  • onlyNewJobs monitoring — run it on a schedule and every run delivers (and bills) only postings you haven't seen before. A run where nothing is new delivers 0 rows, says so plainly, and costs nothing. See Turn it into a job alert.
  • Annualized salaries — hourly/weekly/monthly figures are converted to yearly (×2080 / ×52 / ×12) so salary_min/salary_max are comparable across boards, with a sanity guard against absurd conversions.
  • Descriptions — a 500-character description_snippet on every row that has one (88% of rows on the 2026-08-15 default run), and the full HTML-stripped text via includeDescription.

No API keys, no proxies, no login. All ten sources are public, keyless endpoints.

What you get

One row per remote job:

{
"title": "Director, GTM Strategy & Analytics",
"company": "Temporal Technologies",
"location": "Anywhere in the World",
"remote": true,
"salary_min": 260000,
"salary_max": 326000,
"salary_currency": "USD",
"salary_interval": "yearly",
"salary_source": "description",
"url": "https://weworkremotely.com/remote-jobs/temporal-technologies-director-gtm-strategy-analytics",
"source_board": "weworkremotely",
"posted_at": "2026-08-15",
"tags": ["Product"],
"description_snippet": "Headquarters: United States - Remote Opportunity About Us Temporal is an open source programming model that can simplify code…",
"description": null,
"scraped_at": "2026-08-15T20:15:17Z"
}

(A real row from a live test run on 2026-08-15. That run delivered 100 deduplicated jobs from 9 boards with 6 cross-board duplicates merged — 35% of rows carrying a salary, 88% a description snippet and 100% a posting date, all measured on that run, not estimated.)

Input

FieldTypeDefaultWhat it does
searchTermsarray of strings[] (everything)Keywords matched against job titles, case-insensitive. A job matches if any term matches (OR). A multi-word term needs every word in the title — "python developer" requires both, so prefer short terms like "python" for recall. Empty returns every remote job the boards offer. Capped at 10 terms per run — extras beyond the first 10 are ignored and the run's status message notes it.
matchDescriptionsbooleanfalseWiden matching from titles to tags + the first 500 characters of the description (exactly what ships in tags and description_snippet, so you can always see why a row matched). Measured 2026-08-15 with ["python"]: 28 rows title-only vs 194 rows widened — ~7× the recall, at a precision cost: a marketing role whose blurb mentions "our Python stack" now matches too.
boardsmulti-selectall tenWhich boards to sweep: remoteok, weworkremotely, working_nomads, devitjobs_us, devitjobs_uk, muse, remotive, jobicy, himalayas, hn_hiring.
maxItemsinteger (1–1000)100Maximum number of deduplicated jobs to return. Results are interleaved round-robin across boards, so a small cap still samples every board instead of just the biggest feed.
includeDescriptionbooleanfalsetrue fills the description column with the job's full HTML-stripped text (avg ~4,300 chars measured). Off by default to keep rows light — the 500-char description_snippet is always on.
onlyNewJobsbooleanfalseDeliver only postings this exact search has never delivered before. See Turn it into a job alert.

Running with completely empty input {} works and returns up to 100 jobs from all boards.

Output columns

ColumnNotes
title, company, locationlocation is exactly what the board provides — often a country restriction like "USA Only" or "Anywhere in the World".
remoteAlways true — non-remote rows (DevITjobs office jobs, onsite HN posts) are filtered out before delivery.
salary_min, salary_max, salary_currency, salary_intervalOnly when the board publishes a figure — 35% of rows on the 2026-08-15 default run (DevITjobs ~100%, Himalayas/Remotive/WWR/HN partial, The Muse and Working Nomads none). Hourly/weekly/monthly figures are annualized (×2080 / ×52 / ×12) so salary_interval normally reads yearly and figures are comparable across boards; a magnitude guard suppresses conversions that could only be wrong (an "hourly" $50,000 stays raw rather than shipping as $104M). salary_source says whether the figure was a structured field (direct_data) or parsed out of the posting text (description). Currency is left null when the board doesn't state it — no guessing.
urlDirect link to the posting (for Remote OK rows this is the job's Remote OK page, as their API terms require).
source_boardWhich board this (first) copy of the job came from.
posted_atPosting date, YYYY-MM-DD, when the board provides one.
tagsSkills/technologies/categories as the board tags them.
description_snippetAlways on: the first 500 characters of the HTML-stripped description — filled on 88% of rows (measured; DevITjobs publishes no description text).
descriptionFull HTML-stripped description text when includeDescription: true, else null.

Run it from your code

JavaScript (apify-client):

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });
const run = await client.actor('flash_scraper/remote-job-aggregator').call({
searchTerms: ['python', 'data engineer'],
maxItems: 200,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`${items.length} remote jobs`, items[0]);

Python (apify-client):

from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("flash_scraper/remote-job-aggregator").call(run_input={
"searchTerms": ["python", "data engineer"],
"maxItems": 200,
})
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(len(items), "remote jobs")

curl (run synchronously and get the dataset back):

curl -sX POST \
"https://api.apify.com/v2/acts/flash_scraper~remote-job-aggregator/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"searchTerms": ["python"], "maxItems": 100}'

Turn it into a job alert (onlyNewJobs)

Set onlyNewJobs: true and the actor becomes a monitor: every run delivers — and bills — only postings this exact search (same searchTerms + boards) has never delivered before.

How it behaves, run by run:

  1. First run = baseline. Delivers everything currently matching and the status message says the baseline was saved.
  2. Every later run delivers only new postings. If nothing is new, the run finishes SUCCEEDED with Nothing new since your last run (<time> UTC): … You were not charged. — zero rows, zero cost. That message is the monitor working, not an error.
  3. Memory lives in a named key-value store in your own Apify account (remote-job-monitor), one record per search signature; entries are pruned after 90 days, so a job reposted after a long silence counts as new again.

Set up the alert in 2 minutes (Apify Console):

  1. Open this actor → Input: set your searchTerms, tick Only new jobs, and set maxItems generously (e.g. 500–1000) — with onlyNewJobs on, the sweep reads each board to full feed depth so nothing hides behind the cap, and you still only pay for what's delivered.
  2. Run it once manually — that's your baseline.
  3. Schedules → Create new → pick this actor → cron like 0 8 * * * (daily 08:00). The schedule reuses your saved input.
  4. Add a notification: Integrations on the actor → webhook on Run succeeded to Slack/email/n8n — or read the dataset from the run; on a nothing-new day the dataset is simply empty and you paid nothing.

Two honest notes: if a baseline run hits maxItems, the overflow postings are still "never delivered" and will arrive on the next run(s) until the backlog drains — deliver-once semantics, never deliver-never. And changing searchTerms or boards starts a fresh signature with its own baseline.

Schedule it (n8n, Make, Zapier)

A remote job aggregator earns its keep on a schedule — a daily sweep feeding a Slack channel, an Airtable base, or a job-alert newsletter:

  • n8n: use the Apify node (or an HTTP Request node hitting the run-sync-get-dataset-items endpoint above) on a Cron trigger, then map the JSON rows to Slack/Notion/Google Sheets nodes.
  • Make (Integromat): the Apify app has a "Run an Actor" module — pair it with a scheduled scenario and an Iterator over the dataset items.
  • Zapier: the Apify integration offers "Actor Run Finished" as a trigger — schedule runs natively in the Apify Console (Schedules → new schedule → pick this Actor) and let Zapier fan the fresh dataset out.
  • Apify Console alone also works: Schedules can run this Actor daily and email you or push to a webhook when a run finishes.

Tip for monitoring pipelines: turn on onlyNewJobs (section above) so the scheduled runs deliver only the delta — no downstream dedup needed and quiet days cost nothing.

Honest limits

  • Feed-limited depth. These are public feeds, not archives: RemoteOK serves its ~100 newest rows, WeWorkRemotely ~100 per feed, Working Nomads ~50 curated rows, Jobicy 50 per call. A run samples the current face of each board; it cannot paginate years back.
  • Keyword matching is title-only by default (deliberately — that's the billing gate; you're never charged for a fuzzy server-side match that isn't really your keyword). A Python job titled "Backend Engineer" won't match "python" unless you set matchDescriptions: true, which trades precision for ~7× recall (measured) — the term then only needs to appear in the tags or the first 500 chars of the description.
  • Salary coverage varies by board — 35% of rows overall on the measured default run. DevITjobs publishes structured annual salaries on ~100% of its rows; Himalayas, Remotive, WWR and HN partially; RemoteOK ~3%; The Muse and Working Nomads none. Figures parsed out of free text (salary_source: "description") are conservative best-effort, and annualization only multiplies figures whose interval the board or text actually states.
  • DevITjobs contributes remote rows only (~8% of its inventory, measured) — it's a city-based board, and shipping its office jobs with remote: true would be a lie. Its .uk feed is also geo-sensitive and can be unavailable from some networks; failures are reported per board, never silently.
  • HN "Who is hiring?" rows are parsed from community-formatted posts (Company | Role | Location | Salary). Parsing degrades gracefully, but expect the occasional imperfect company/title split. Only posts that explicitly say "remote" are included.
  • Boards change. Undocumented internal APIs (DevITjobs in particular) can change shape without notice. A board that fails is named in the run's status message and log; its failure never poisons the other nine.
  • Attribution: job rows sourced from Remote OK link back to the job's Remote OK page in the url column, as their API terms require.
  • Zero matches cost nothing. A run that delivers no rows tells you why (boards empty vs. your filters) and does not charge you.

Need LinkedIn, Indeed and Glassdoor too - merged and deduplicated across 12 boards with only-new-jobs monitoring? -> Multi Job Board Scraper