Remote Jobs Scraper: We Work Remotely, RemoteOK, Python.org avatar

Remote Jobs Scraper: We Work Remotely, RemoteOK, Python.org

Pricing

from $1.40 / 1,000 jobs

Go to Apify Store
Remote Jobs Scraper: We Work Remotely, RemoteOK, Python.org

Remote Jobs Scraper: We Work Remotely, RemoteOK, Python.org

Remote and work-from-home job listings from We Work Remotely, Remote OK and Python.org Jobs in one clean format, with salary, employment type and categories. Filter by keyword, region, category or date, merge duplicates across boards, or get only jobs new since your last run. Links to each source.

Pricing

from $1.40 / 1,000 jobs

Rating

0.0

(0)

Developer

Michael Costa

Michael Costa

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

1

Monthly active users

2 hours ago

Last modified

Categories

Share

What does Remote Jobs Scraper do?

Remote Jobs Scraper collects remote and work-from-home job listings from We Work Remotely, Remote OK and Python.org Jobs (its remote postings) through their official public feeds, and returns them in one clean format, filtered by keyword, region, category or date, with the same job on several boards merged into one record. No login.

The listings belong to the boards and the employers who posted them. Every record says which board it came from and links to the original listing there.

Input fields · API · Use it from Claude, ChatGPT or Cursor (MCP)

Jump to: Monitor · Fields · Price · How to use · Input · Output · Sources · AI agents (MCP) · Limits · FAQ

Try it in one click: the input comes pre-filled with all three boards and a limit of 50 jobs, newest first. That's roughly $0.10 (50 × $0.002 per job, plus $0.00005 for the run start). Then add your own keywords, regions or categories.

Monitor new remote jobs

Remote Jobs Scraper can check the boards on a schedule and give you only the jobs you haven't had yet. Set it up once:

  1. Save a task. Set your Keywords, Locations / regions or Categories, turn on Only jobs new since my last run (onlyNewJobs: true in the API), then click Save as a new task at the top right of the actor's page. The first run returns everything that matches (up to Max jobs per run); later runs return only jobs you haven't had yet.
  2. Schedule it. In Apify Console, open Schedules, click Create new, pick the task and set how often it runs (for example every 6 hours, cron 0 */6 * * *).
  3. Send the new jobs where you work, from the task's Integrations tab:
    • Slack: a message in the channel you choose when a run succeeds (you pick the events and can edit the message).
    • Email: Send results email via Gmail sends the run's results, with the dataset attached.
    • Webhook: a POST to your URL on the ACTOR.RUN.SUCCEEDED event. The payload's resource.defaultDatasetId points to the new jobs: GET https://api.apify.com/v2/datasets/<defaultDatasetId>/items?format=json with your API token.
    • Make, Zapier or n8n: each has an Apify step that starts on a finished run and reads its dataset.

A run that finds nothing new returns 0 jobs and costs only the $0.00005 start fee. Slack and email are sent for every successful run, including a quiet one; to hear only about new jobs, use the webhook or Make/Zapier/n8n and skip runs whose dataset is empty. Add the run failed event too, so a failed run doesn't go unnoticed. Keep the task's filters fixed: the memory is per board and per filter combination, so changing them starts a fresh search. If you republish the jobs, keep each job's source and url (see the boards' terms below).

What data does Remote Jobs Scraper return?

FieldExampleNotes
titleSoftware Developer Security Analytics
companyNameRedMimicry
source, urlRemote OK, https://remoteOK.com/remote-jobs/...The board and the original listing: keep both when you use the job.
location, locations, countryGeorgia, United States, United StatesWhere candidates can work from; country only when exactly one country is named.
employmentTypeFULL_TIMEOne of FULL_TIME, PART_TIME, CONTRACT, TEMPORARY, INTERNSHIP, VOLUNTEER, or null.
postedAt2026-09-22T09:00:01ZISO 8601 UTC; null for Python.org jobs (its feed has no dates).
salaryMin, salaryMax, salaryCurrency, salaryPeriod69000, 77000, EUR, YEARnull when the listing gives no pay.
salaryText, salarySourceEUR 69,000 – 77,000, descriptionats from the board's salary field, description from the job text.
categories, tagssoftware-development, golangEvery board's categories mapped onto one list.
descriptionRemote - Location: Mostly remote...Plain text.
alsoListedOn[]The same job on another board, when it was merged.
idremoteok:redmimicry:1137417Stable across runs, for deduplication.

Every job has the same fields; the full record is under Output.

How much does it cost to scrape remote jobs?

You pay per job returned: $2.00 per 1,000 jobs, plus $0.00005 each time a run starts. Filters and duplicate merging happen before you're charged, so you only pay for jobs you keep, and a repeat run with nothing new costs only the start fee.

It's cheaper on paid Apify plans: $1.80 per 1,000 jobs on Starter, $1.60 on Scale and $1.40 on Business. The prices on this page are the Free-plan price, so on a paid plan you pay less than the examples show.

  • The example below: 50 jobs × $0.002 = $0.10, plus the $0.00005 start fee.
  • A month, for example: a first run of all ~350 current jobs ($0.70), then, if about 40 new jobs a day match your filters, 1,200 × $0.002 = $2.40: about $3.10, plus the run starts.
  • Caps: Max jobs per run in the input (pre-filled with 50 in the form, 100 when an API call leaves it out; raise it, e.g. to 1000, for every matching job), and Maximum cost per run in the run options; it stops cleanly at whichever comes first. Jobs are returned newest first. If the maximum cost doesn't cover a single job, nothing is fetched at all.

How to scrape remote jobs

  1. Open the actor. All three boards are selected under Job boards.
  2. Add Keywords (e.g. python), Locations / regions (e.g. Europe) or Categories to narrow the list.
  3. Click Start.
  4. Open the Output tab and export the jobs as JSON, CSV or Excel, or read them through the API.
  5. For job alerts, save it as a task and schedule it (see Monitor new remote jobs above).

Example: the newest 50 jobs, then the next run

The pre-filled input (all boards, the 50 newest jobs), with Only jobs new since my last run turned on:

{"sources": ["weworkremotely", "remoteok", "pythonorg"], "maxResults": 50, "onlyNewJobs": true}

One of the 50 jobs (real output from a local run on 2026-09-25; description and tags shortened):

{
"id": "remoteok:redmimicry:1137417",
"platform": "remoteok",
"source": "Remote OK",
"companyName": "RedMimicry",
"title": "Software Developer Security Analytics",
"remote": true,
"employmentType": "FULL_TIME",
"postedAt": "2026-09-22T09:00:01Z",
"url": "https://remoteOK.com/remote-jobs/remote-software-developer-security-analytics-redmimicry-1137417",
"salaryMin": 69000.0,
"salaryMax": 77000.0,
"salaryCurrency": "EUR",
"salaryPeriod": "YEAR",
"salaryText": "EUR 69,000 – 77,000",
"salarySource": "description",
"description": "Remote - Location: Mostly remote (within Germany), with monthly in-person collaboration at our Berli...",
"tags": ["golang", "infosec", "dev", "..."],
"categories": ["software-development", "data", "security"]
}

Where a job can be done from comes back as plain text and a country name. A We Work Remotely listing from the same run, whose employer (headquartered in Atlanta) picked the country Georgia for the US state:

{
"id": "weworkremotely:iterable:iterable-email-deliverability-consultant",
"location": "Georgia, United States",
"locations": ["Georgia, United States"],
"country": "United States"
}

The default input without the 50-job cap returned 349 jobs that day (before Python.org was added). With the cap, a second run straight after returned the next 50 it hadn't returned yet; once the backlog is used up, runs return only newly posted jobs.

Ready-to-run examples

Each example opens with the input already filled in. Run it as it is, or change the input first.

Input

FieldWhat it does
Job boardsWe Work Remotely, Remote OK and Python.org Jobs (remote postings only). All three by default.
KeywordsKeep jobs whose title or tags contain any of these words (case-insensitive).
Exclude title keywordsDrop jobs whose title contains any of these words.
Locations / regionsKeep jobs open to candidates in any of these (e.g. USA, Europe, Germany), matched against the listing's location or region. A country's short form finds its full name (USA finds "United States", UK "United Kingdom"). Jobs open worldwide always match; jobs that give no location are dropped.
CategoriesKeep jobs in any of these categories (software development, DevOps, data, security, design, product, customer support, sales and marketing, management and finance, writing, HR, other).
Posted within (days)Only recently published jobs.
Only jobs new since my last runFirst run returns everything that matches; later runs return only jobs you haven't had yet. Remembered in your own Apify storage, per board and per filter combination.
Merge duplicates across boardsOn by default.
Max jobs per runCap the total number of jobs, newest first. Pre-filled with 50 in the console; 100 when left out of an API call. Raise it (e.g. 1000) for every matching job.
{
"sources": ["weworkremotely", "remoteok", "pythonorg"],
"keywords": ["python", "backend"],
"excludeKeywords": ["intern"],
"locations": ["Europe", "Germany"],
"categories": ["software-development"],
"postedWithinDays": 7,
"onlyNewJobs": true,
"maxResults": 200
}

Output

Every job has the same fields. Fields a board doesn't publish are null.

{
"id": "remoteok:omega-enterprises:1137418",
"platform": "remoteok",
"source": "Remote OK",
"sourceUrl": "https://remoteok.com",
"company": "omega-enterprises",
"companyName": "Omega Enterprises",
"title": "Junior Digital Assets Operations Analyst",
"department": null,
"team": null,
"location": null,
"locations": [],
"country": null,
"remote": true,
"workplaceType": "remote",
"employmentType": "PART_TIME",
"postedAt": "2026-09-22T14:36:54Z",
"updatedAt": null,
"url": "https://remoteOK.com/remote-jobs/remote-junior-digital-assets-operations-analyst-omega-enterprises-1137418",
"applyUrl": "https://remoteOK.com/remote-jobs/remote-junior-digital-assets-operations-analyst-omega-enterprises-1137418",
"salaryMin": 60000,
"salaryMax": 80000,
"salaryCurrency": "USD",
"salaryPeriod": "YEAR",
"salaryText": "USD 60,000 - 80,000 per year",
"salarySource": "ats",
"description": "Plain-text job description…",
"tags": ["other", "crypto", "remote", "education", "web3", "bitcoin", "ethereum", "part time", "finance",
"blockchain", "defi", "junior", "analyst", "ops"],
"categories": ["management-finance"],
"alsoListedOn": [],
"scrapedAt": "2026-09-24T16:00:00Z"
}
  • source and url: the board and the original listing. Keep both when you use the job.
  • location, locations and country: where candidates can work from, as the board lists it, cleaned up. country is a plain country name ("United States", "South Korea") when the listing names exactly one country, else null: several countries, a region ("North America"), a city with no country ("London"), or nothing.
    • We Work Remotely: "Anywhere in the World" becomes Worldwide, used only when the listing names nothing narrower; a state is given with its country ("California, United States"); several places are separated by ; in location and listed one by one in locations. The boards' flag emojis and long official names ("United Kingdom of Great Britain and Northern Ireland") are replaced by short names. Employers in the US state of Georgia often pick the country Georgia: a listing whose only country is Georgia (or Georgia and the US) is read as the US state when anything in it points to the US (the US itself, a US state, or a headquarters line such as "Atlanta" or ", GA"); otherwise it stays the country.
    • Remote OK: the employer's own text, with repeated and empty parts removed ("Austin, Austin, Texas, United States" becomes "Austin, Texas, United States"); country is read from its last part when that names a country or a US state. A bare "Georgia" is left as an unknown country.
    • Python.org Jobs: the posting's location line, cleaned the same way ("Remote, Remote, Worldwide" becomes "Remote, Worldwide").
  • description: plain text. For Remote OK jobs it ends with Remote OK's anti-spam line, unchanged (see below).
  • postedAt: a listing dated in the future (it happens) is given the run's time instead. Python.org's feed publishes no dates, so its jobs have postedAt: null: Posted within (days) keeps them (undated jobs are never silently dropped) and they come after the dated jobs, newest first.
  • Python.org Jobs is a Python job board, not a remote one: only postings whose location or title says remote, anywhere, worldwide or telecommute are returned. Each is tagged python; its employment type is null (the feed doesn't give one).
  • alsoListedOn: the same job on other boards, each with source, url and id.
  • salarySource: ats when the board's own salary field gave it, description when it came from the job text.
  • id is stable across runs, so you can use it to deduplicate.

Where the remote jobs come from, and the boards' terms

Each board allows its listings to be reused on conditions, and this actor keeps them. If you publish the jobs somewhere, you need to keep them too:

BoardWhat it asksWhat the actor does
We Work Remotely (terms)"Anyone can use the feed, all we ask is that you attribute the links back to We Work Remotely."Every record has source and the original listing url on weworkremotely.com.
Remote OK (API terms, legal)Link back to the job's URL on Remote OK (a normal "follow" link, no nofollow) and mention Remote OK as the source, wherever you use the data. Don't use the Remote OK logo.Every record has source and its Remote OK url. No logos are included. Requests keep the 1-second crawl delay in Remote OK's robots.txt.
Python.org Jobs (legal statements, feed)Job postings are the employers' content, and under "Third-Party Content" their providers "grant the PSF and all other users of the web site an irrevocable, worldwide, royalty-free, nonexclusive license to reproduce, distribute, transmit, display, perform, and publish such content". The rest of python.org is the PSF's, all rights reserved.Only the postings from the public jobs feed are taken, nothing else from python.org. Every record has source and the posting's url on python.org. One request per run.

Never present these jobs as your own postings, and keep each job's source and url wherever you show it. The actor identifies itself honestly to each board and follows each board's robots.txt.

Remote OK's anti-spam line: every Remote OK description ends with a line like "Please mention the word … and tag … when applying". It is part of how Remote OK protects its listings and traces reuse, so the actor passes it on exactly as Remote OK wrote it, in description, and does not strip or change it.

Run it on a schedule, or from your own code

  • Schedule: save the input as a task and add it to a schedule, as in Monitor new remote jobs above.
  • API: fetch a task's latest results with GET https://api.apify.com/v2/actor-tasks/<task id>/runs/last/dataset/items?status=SUCCEEDED&format=csv and your API token (format can also be json or xlsx).
  • Webhooks and automation: a webhook when a run succeeds, or Make, Zapier or n8n through Apify's integrations.

Can I use Remote Jobs Scraper from an AI agent (MCP)?

Yes, through Apify's MCP server, from Claude, ChatGPT, Cursor or any other MCP client. Add this to your client's MCP configuration (or let the agent find it with the server's actor search); your client signs you in to Apify:

{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com?tools=humble-echidna/remote-jobs"
}
}
}

To use an Apify API token instead of signing in, add "headers": {"Authorization": "Bearer <APIFY_TOKEN>"} next to url.

The agent passes the same input JSON as above. Have it set Max jobs per run (maxResults) to keep answers small.

Who it's for

Remote-job boards and newsletters that republish listings (with the attribution the boards ask for), people running their own remote-job alerts, and salary and market research (pay ranges as numbers, with currency and period, across boards). The recurring job: schedule it every few hours with Only jobs new since my last run, and each run returns a deduplicated list of the jobs you haven't had yet, in the same format as our company career-page scrapers.

Why this one?

  • One flat price, no usage bill. You pay per result at the price above and nothing else: no compute, proxy or storage charges on top, apart from the $0.00005 run-start fee, so you know what a run costs before it starts. Results you don't get aren't charged.
  • Three boards, one format. Employment type is always one of FULL_TIME, PART_TIME, CONTRACT, TEMPORARY, INTERNSHIP, VOLUNTEER; dates are ISO 8601 UTC; each board's categories and tags are mapped onto one category list. The format is the same as our Company Career Page Jobs Scraper, so results from both can go in one table.
  • Duplicates merged. When the same company posts the same job title on several boards, you get it once: the most complete listing, with the other boards' listings kept in alsoListedOn (name and link).
  • Salary as numbers with currency and period, from the board's own salary field, or from the job text when the employer wrote the pay range there ("$100,000-$125,000", "£20–£40/hour"). Obvious placeholders (a range of "1 - 2", or "10,000 - 750,000") are dropped rather than passed on.
  • Only new jobs since your last run, for job alerts on a schedule.
  • Attribution built in. Every record carries the source and original url the boards' terms ask for.
  • Reliable. A board that's down never affects the others in your run, and a listing that doesn't parse is skipped instead of failing its board. The run log and the RUN_STATS record say exactly which board had a problem and why.

Limits

  • Each board's feed carries its recent listings, not its whole archive: currently about 100 on Remote OK, each We Work Remotely category's current listings (about 250 in total), and the 20 newest Python.org postings (about half of them remote). Running regularly with Only jobs new since my last run is how you build a complete history.
  • The location filter matches words, not geography: Europe doesn't match a job that only says Germany. Add both. A job whose only location is a city ("Stockholm", "London") has no country, so a country filter won't match it.
  • Three boards only (see the FAQ for why). Python.org jobs have no posting date.

FAQ

Can I publish these remote jobs on my own site?

The boards allow it on their conditions: credit the board and link each job to its original listing (a normal "follow" link for Remote OK), and don't present the jobs as your own postings. Read each board's terms (linked above) before you do.

Why only these three boards?

The actor only includes boards whose published terms allow this kind of automated, commercial reuse in a way it can keep for every user, with a public feed that needs no key and that robots.txt allows. More than 25 other job boards were reviewed (September 2026) and left out for now: most license their listings for personal, non-commercial use only or forbid automated access; some ask that their jobs not be passed on to other job sites or job boards; some need an API key or registration; some limit how often they can be polled in a way that can't be guaranteed across many users running the actor at once; and some have no feed at all. More boards may be added when their terms fit.

Why does something that used to work now fail or return fewer results?

A board may have changed its feed without notice, or one of its feeds may be down. The run's status message and log name the board and what went wrong (a whole board, or one of We Work Remotely's category feeds), and the rest of the run is unaffected. With Only jobs new since my last run, jobs that were missing only because a feed failed are not returned again once it recovers. Please open an issue with the input you used.

It reads only the official public feeds of these boards, whose terms allow reuse (quoted above: We Work Remotely and Remote OK on attribution, Python.org by the licence its posters grant every user of the site), follows their robots.txt and their stated conditions, uses no login or key, and collects no personal data: job listings only. Keep each job's source and url wherever you use it.

ActorUse it when
Company Career Page Jobs ScraperYou want every open job from companies you name, straight from their career pages (Greenhouse, Lever, Ashby, Recruitee, Personio, Teamtailor), in this same format, so both can go in one table.
Dataset TransformerYou want to filter, dedupe and export CSV for a job board or newsletter.

Feedback and support

Found a bug, or need a field or board that isn't here? Open an issue on the Issues tab with the input you used.

Versions

Current version: 1.2. See the Changelog tab for what changed in each version.