We Work Remotely Jobs Scraper
Pricing
from $0.76 / 1,000 jobs
We Work Remotely Jobs Scraper
Scrape every remote job on We Work Remotely: title, company, salary band and real salary, region and countries, skills, full description, badges. Filters, monitoring of new and closed jobs. Export to JSON, CSV or Excel.
Pricing
from $0.76 / 1,000 jobs
Rating
0.0
(0)
Developer
Nice Dev
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
2 days ago
Last modified
Categories
Share
💼 What is We Work Remotely Jobs Scraper?
We Work Remotely Jobs Scraper extracts every remote job from We Work Remotely: title, company, salary band and the real salary written in the job, region and countries (ISO codes), skills, full description, badges, apply link and, as options, the company profile and the e-mail addresses published on the company's own website. It works as a We Work Remotely API alternative: run it on a schedule, call it from your code, or plug it into Make, Zapier or n8n.
Pick one or more categories (or leave them empty for the whole site), add a keyword (python) or paste any We Work Remotely URL, click Start, and download the jobs in JSON, CSV or Excel. No login, nothing to set up, and it is fast: about 100 jobs in 20 seconds.
📋 What data can you extract from We Work Remotely?
One item per job, 66 fields:
| Category | What you get |
|---|---|
| 💼 Job | title, link, job type (full-time, contract), category, seniority (junior … director), skills — Staff Software Engineer, Full-Time |
| 🏢 Company | name, logo, headquarters, Top 100 remote company or not, We Work Remotely company page |
| 🌍 Where you can work from | region as written (USA Only, Europe…), countries and their ISO codes, state, worldwide or not, time zones asked |
| 💵 Salary | the site's yearly band and the real amount written in the job: minimum, maximum, currency, per year / month / hour — $162,400—$290,000 USD |
| ⭐ Badges | featured, boosted, hot, pinned, new |
| 🕒 Dates | posting date, expiry date, age in days, days left — what the date filters read |
| 📝 Description | full text and HTML, visa sponsorship, relocation help |
| 📨 How to apply (job page) | apply link and type (employer's page, e-mail, We Work Remotely account), the apply e-mail when the employer gives one, exact list of countries accepted |
| 🏷️ Company profile (option) | website, address, number of open jobs, About text (when the company wrote one), remote and diversity policy links, benefits, hiring process |
| 📇 Company contacts (option) | e-mail addresses, phone numbers and social links published on the company's own website |
| 🔔 Monitoring | active or closed (taken down since the last run), date closed, first seen, which of your keywords matched |
Every field, with an example, is listed in the Output section below.
The apply link and type, the exact countries accepted, the company website, address and number of jobs posted come from the job page: they are filled when Extract job page details is on (extractDetails). The company profile needs Add the company profile, the contacts Email from the company website. Without them the run reads only the job lists, and is much faster.
✅ Why use We Work Remotely Jobs Scraper?
- 🌍 The whole site in one run: every category, about 400 jobs, or just the ones you pick — about 100 jobs in 20 seconds, the whole site with every job page in about 11 minutes.
- 💵 The real salary, not only the band: when the job states an amount (
$140K-$180K,€83,000 annually), you get its minimum, maximum, currency and period, and where it was read. A job that lists a range per place (« San Francisco … all other locations, including remote … ») gives the range for remote workers. - 🗺️ Countries you can filter on: ISO codes, worldwide or not, the exact list of countries the employer accepts, the time zones the job asks for.
- 🎯 Filters the site does not have: salary minimum / maximum, seniority, skills, title words, companies to keep or drop, featured / Top 100 / hot jobs, posting dates.
- 🔔 Monitoring built in: tick Only new jobs, schedule the Actor, and each run returns (and charges) only the jobs it has never delivered — and, if you want, the jobs taken down since.
- 📇 Company contacts: the e-mail addresses, phone numbers and social links published on each company's own website, once per company.
- 🔌 API, scheduling, monitoring, integrations (Make, Zapier, n8n, Google Sheets…), proxy rotation and JSON/CSV/Excel export via the Apify platform.
🚀 How to scrape We Work Remotely
- Create a free Apify account.
- Open We Work Remotely Jobs Scraper, pick some Categories (empty = all) and, if you want, type a Search keyword (e.g.
python). - Or paste your own We Work Remotely URLs into Start URLs: category pages, search pages, company pages or single job pages.
- Set Max jobs (100 by default, 0 = no limit), the filters you need, tick Extract job page details for the apply link and the exact countries, then click Start.
- Download the dataset in JSON, CSV, Excel or via API.
💰 How much does it cost to scrape We Work Remotely?
This Actor uses pay per event pricing: you pay for the jobs you get and for the options you tick, never for a blank row. Platform usage (compute, proxy) is included in the price.
| Event | When it is charged | Free | Bronze | Silver | Gold |
|---|---|---|---|---|---|
| Job | each job saved from the job lists (Extract job page details off) | $0.79 | $0.78 | $0.77 | $0.76 |
| Job with details | each job saved with its job page read (Extract job page details on, or a job URL pasted), instead of a Job | $0.88 | $0.87 | $0.86 | $0.85 |
| Company profile | each company profile added (Add the company profile), once per company per run | $0.89 | $0.88 | $0.87 | $0.86 |
| Apply e-mail | each application e-mail address delivered (Add the apply e-mail) | $0.77 | $0.76 | $0.75 | $0.74 |
| Company e-mail | each company whose own website gives at least one e-mail address (Email from the company website), once per run; phone numbers and social links found alone are free | $0.88 | $0.86 | $0.81 | $0.77 |
| Closed job | each job reported as taken down (Report jobs taken down), instead of a job | $0.36 | $0.35 | $0.34 | $0.33 |
| Filter check | each job read from the job lists and dropped by one of your filters: filtering never costs more than taking everything | $0.044 | $0.034 | $0.024 | $0.014 |
| Job page filter check | each job page read (Extract job page details) and dropped by a filter that needs that page | $0.17 | $0.16 | $0.15 | $0.14 |
Prices are per 1,000 events. Plus $0.01 per run start ($1 per 100 runs). Every option is off by default: you only pay for what you tick.
- The whole site, about 400 remote jobs, ≈ $0.33 (≈ $0.37 with every job page read).
- A daily monitor of 30 new jobs (
onlyNew) ≈ $0.034 a day. - The $5 of free credits every Apify account starts with already cover about 6,000 jobs.
A job your filters drop is never saved nor charged as a job (only its small filter check), and you never pay twice for the same job (onlyNew).
⚙️ Input
The jobs of two categories that mention Python:
{"categories": ["remote-full-stack-programming-jobs", "remote-back-end-programming-jobs"],"query": "python","maxItems": 100}
Several keywords and places, a salary floor, only recent jobs, with their job page:
{"searchQueries": ["react", "typescript"],"locations": ["Europe", "Germany"],"minSalary": 80000,"postedAfter": "7 days","extractDetails": true,"maxItemsPerQuery": 50,"maxItems": 300}
Daily monitoring of the design jobs: the new ones, and the ones taken down since the last run:
{"categories": ["remote-design-jobs", "remote-product-design-jobs", "remote-ux-ui-design-jobs"],"onlyNew": true,"includeClosedJobs": true,"stateKey": "design-daily","maxItems": 0}
Or with your own URLs, plus the company profile and its contacts:
{"startUrls": [{ "url": "https://weworkremotely.com/remote-jobs/search?term=python" },{ "url": "https://weworkremotely.com/company/zapier" }],"extractDetails": true,"includeCompanyProfile": true,"enrichEmails": true}
| Field | Notes |
|---|---|
categories | Job categories to read, e.g. remote-design-jobs, remote-customer-support-jobs. Empty = every category (the whole site). Ignored when startUrls is set. |
startUrls | Category pages (https://weworkremotely.com/categories/remote-design-jobs), search pages (https://weworkremotely.com/remote-jobs/search?term=python), the full-time / contract pages, company pages (https://weworkremotely.com/company/zapier) or single job pages. Keywords, filters, caps and monitoring still apply. |
query, searchQueries | Keep only the jobs whose title, company, skills or description contain one of these words or phrases (python, customer success), case and accents ignored. matchedKeywords tells which one matched. |
location, locations, includeWorldwide | Keep only the jobs open to one of these places (Germany, Europe, United States), matched against the region, the countries and the headquarters. Jobs open to anyone are kept too, unless includeWorldwide is unticked. A job limited to a wider area without a list of countries (Europe, EMEA) is kept unless extractDetails reads its exact countries. |
worldwideOnly | Keep only the jobs open to applicants anywhere in the world. |
maxItems | Stop after this many jobs for the whole run (0 = no limit). |
maxItemsPerQuery | Cap for EACH category or start URL, so that the first one cannot use up the whole budget (0 = no cap). |
sortBy | Which jobs maxItems and the per-category cap keep: newest, oldest or salary (highest first, in US dollars: the band of the site or an amount in USD; a salary in another currency without a band is ranked with the jobs without a salary, last). The order is made inside each category or start URL, not across them; with extractDetails the rows are saved as the job pages arrive. |
extractDetails | Open each job page for the apply link, the exact countries accepted, the employer's salary, the company website, address and number of jobs posted (charged as a job with details). |
includeCompanyProfile | Add each company's We Work Remotely profile, once per company per run. |
includeApplyEmail | With extractDetails: add the application e-mail address when the employer gives one. |
enrichEmails | Visit each company's own website (3 pages at most, once per company per run) for its e-mail addresses, phone numbers and social links. Needs extractDetails or includeCompanyProfile. |
descriptionMaxLength | Cut the plain-text description to this many characters (0 = the full text, up to 32,000 characters); the HTML stays whole. |
jobTypes | Full-Time, Contract. Empty = both. |
salaryRanges | The site's yearly bands, e.g. $100,000 or more USD. Empty = all. |
minSalary, maxSalary, includeNoSalary, onlyWithSalary | Yearly salary in US dollars (80000): the band of the site or the amount written in the job. Jobs without a salary follow includeNoSalary; onlyWithSalary keeps only the jobs that show one. |
seniority | Levels read from the title: junior, senior, lead, manager… Jobs whose title names no level are dropped when this list is set. |
titleKeywords, skills | Keep the jobs whose title (engineer, designer) or skills (React, SEO) contain one of these words. |
includeCompanies, excludeCompanies | Companies to keep or drop, by name or company page slug (zapier), case ignored. |
onlyFeatured, onlyTop100, onlyHot | Keep only the featured jobs, the jobs of the Top 100 remote companies, or the hot jobs. |
postedAfter, postedBefore | Posting date range: 2026-09-01, or a period before now (7 days, 2 weeks, 1 month, 24 hours). |
excludeKeywords | Drop the jobs whose title contains one of these words (senior, intern), case and accents ignored. |
stateKey, onlyNew, resetState, includeClosedJobs | Monitoring: onlyNew returns only the jobs never delivered under this memory key (design-daily); includeClosedJobs also reports, once, the jobs taken down since; resetState forgets the memory. |
| Advanced | proxyConfiguration (Apify proxy by default, included in the price; the residential proxy is not available), maxConcurrency, maxRequestsPerMinute, minRequestIntervalMs, maxRequestRetries, debugLog. |
📦 Output
A real job from a test run, shortened: the description is cut, and some empty or option fields are left out (the full list is below).
{"id": "samsara-staff-software-engineer","url": "https://weworkremotely.com/remote-jobs/samsara-staff-software-engineer","title": "Staff Software Engineer","status": "active","companyName": "Samsara","companySlug": "samsara","companyUrl": "https://weworkremotely.com/company/samsara","companyHeadquarters": "Remote","isTop100Company": false,"category": "Full-Stack Programming","categories": ["Full-Stack Programming"],"jobType": "Full-Time","region": null,"countries": ["United States of America"],"countryCodes": ["US"],"state": "California","isWorldwide": false,"applicantCountries": ["US"],"skills": [],"salaryRange": "$100,000 or more USD","salaryMin": 162400,"salaryMax": 290000,"salaryCurrency": "USD","salaryPeriod": "year","salaryText": "$162,400—$290,000 USD","salarySource": "description","seniority": "lead","isFeatured": true,"isHot": true,"isPinned": true,"publishedAt": "2026-09-16T13:57:14.000Z","firstPublishedAt": "2026-08-17T13:57:14.000Z","expiresAt": "2026-10-16T13:57:14.000Z","ageDays": 29,"description": "About the role:\n\nSamsara (NYSE: IOT) sits at the center of hardware, software, AI, and the physical world. […]","relocationOffered": false,"timezoneRestrictions": [],"matchedKeywords": ["engineer"],"applyUrl": "https://weworkremotely.com/job-seekers/account/register?alert=Create+an+account+to+view+full+job+details.","applyType": "account","applyEmail": null,"directApply": false,"companyWebsite": "https://www.samsara.com/","companyDomain": "samsara.com","companyJobsPosted": 6,"companyEmails": [],"companyPhones": [],"companySocialLinks": [],"searchUrl": "https://weworkremotely.com/categories/remote-full-stack-programming-jobs","scrapedAt": "2026-10-16T08:20:56.239Z"}
You can download the dataset in various formats such as JSON, HTML, CSV or Excel.
All 66 fields
| Fields | What you get |
|---|---|
id, url, title, status | Job: job slug, job page, title, active or closed |
companyName, companySlug, companyUrl, companyLogoUrl, companyHeadquarters, isTop100Company | Company: Samsara, samsara, its We Work Remotely page, logo, Remote, false |
category, categories, jobType, seniority, skills | Full-Stack Programming (every category of the job in categories), Full-Time or Contract, lead, ["Java", "PostgreSQL", "Spring"] |
region, countries, countryCodes, state, isWorldwide, applicantCountries, timezoneRestrictions | Where you can work from: USA Only, ["United States of America"], ["US"], California, false, exact ISO list from the job page, ["CET"] |
salaryRange, salaryMin, salaryMax, salaryCurrency, salaryPeriod, salaryText, salarySource | Salary: $100,000 or more USD, 162400, 290000, USD, year, the sentence as written, description / jobPage / band |
isFeatured, isBoosted, isHot, isPinned, isNew | Badges shown by the site |
publishedAt, firstPublishedAt, expiresAt, ageDays, daysUntilExpiry | Dates: ISO 8601 UTC, then whole days (what the date filters read). firstPublishedAt is the date the job was first posted; publishedAt is its latest (re)posting, as the site shows it (the site renews a job every 30 days) |
description, descriptionHtml, visaSponsorship, relocationOffered | full text, full HTML, true / false / null when the job says nothing |
applyUrl, applyType, applyEmail, directApply | How to apply (job page): link, external / email / account / login, e-mail (option), true / false |
companyWebsite, companyDomain, companyAddress, companyJobsPosted | https://www.samsara.com/, samsara.com, address, 6 (all the jobs the company ever posted, from the job page) |
companyOpenJobs, companyDescription, companyRemotePolicyUrl, companyDeiPolicyUrl, companyBenefits, companyHiringProcess | Company profile (option): the jobs the company has open now, then its own texts and links (null when it wrote none) |
companyEmails, companyEmailSource, companyPhones, companySocialLinks | Company contacts (option): e-mails, the page where the first one was found, phone numbers, social links |
closedAt, firstSeenAt, matchedKeywords, searchUrl, scrapedAt | Monitoring: date closed, first delivery, ["engineer"], the page the job was read from, ISO timestamp |
💡 Tips
How to get more results
Leave Categories empty and set maxItems to 0: the run returns every job on the site (about 400). The site shows only open jobs: schedule the Actor daily with onlyNew to keep a history.
How to reduce costs
Leave extractDetails off unless you need the apply link, the exact countries accepted or the company website: a job read from the lists costs less than a job with details. The filters (a job dropped costs only the filter check), maxItems, maxItemsPerQuery and onlyNew for recurring runs (you never pay twice for the same job) do the rest.
Monitoring: new jobs and jobs taken down
Tick Only new jobs (onlyNew) and schedule the Actor. The first run returns everything; each later run skips the jobs already delivered: they are not saved, not charged, and their page is not even opened. The memory lives in a named key-value store of your account (weworkremotely-jobs-scraper-seen, up to 150,000 jobs per key) and is only updated with jobs that really reached the dataset, so a failed run never hides anything. Give each schedule its own stateKey (two schedules sharing a key would hide each other's jobs), and tick resetState once to start over.
Tick Report jobs taken down (includeClosedJobs) as well, and each run also saves, once, every job a previous run delivered that is no longer on its category page, with status = closed and closedAt. It works with categories (not with search or company pages), and only for the jobs delivered by runs where the box was ticked.
Filter by posting date
postedAfter and postedBefore take a date (2026-09-01, the whole day is included) or a period before now (7 days, 2 weeks, 1 month; via the API also 24 hours or a full ISO date-time). The filter reads publishedAt; a job without a posting date is dropped as soon as a date bound is set. Filtered-out jobs are not saved and do not count in maxItems (each job dropped costs the filter check, see Pricing); the run summary tells how many were filtered.
🔌 Integrations and API
Call the Actor via the Apify API, the JavaScript or Python clients, or connect it with integrations and webhooks (Make, Zapier, n8n, Google Sheets, Slack, Airtable…). The dataset can be fetched as JSON or CSV from any tool.
🤖 Use with AI agents (MCP)
AI agents (Claude, ChatGPT, Cursor…) can find and run this Actor through the Apify MCP server, billed to their Apify account like any run. It returns one item per We Work Remotely job. Actor id: nice_dev/weworkremotely-jobs-scraper; MCP server with this Actor only: https://mcp.apify.com/?tools=fetch-actor-details,nice_dev/weworkremotely-jobs-scraper.
Smallest input, for a cheap first call:
{"categories": ["remote-design-jobs"],"maxItems": 10}
Key output fields: url, title, companyName, region, countryCodes, salaryMin, salaryMax, salaryCurrency, publishedAt and applyUrl (with extractDetails).
Cost: $0.79 per 1,000 jobs ($0.76 on Gold) plus $0.01 per run; job pages and the other options are priced in the pricing section above. Cap each call with maxItems and, through the API, with the run option maxTotalChargeUsd.
❓ FAQ
Is it legal to scrape We Work Remotely?
The Actor only reads what We Work Remotely shows publicly to any anonymous visitor. It logs in to nothing and creates no account. Job posts are business data; some of them hold personal data (a recruiter's application e-mail, for instance), which is protected by GDPR: do not store it without a legitimate reason. You are responsible for using the data in compliance with We Work Remotely's Terms of Use and applicable law. This Actor is not affiliated with We Work Remotely.
Where do the e-mail addresses come from?
With enrichEmails on, the Actor reads the pages each company publishes on its own website (home page, contact page, legal notice) and returns the business contact addresses shown there — what any visitor sees. It does not log in, guess addresses, read contact forms or bypass any protection. Some of these addresses are personal data under GDPR (e.g. firstname.lastname@company.com): you are responsible for having a lawful basis before using them, for informing the people concerned and for honouring opt-outs. Rules for B2B e-mail prospecting differ by country (opt-out in some, prior consent in others).
And the phone numbers?
The Actor also returns the phone numbers the company publishes on those same pages (tel: links, the company's structured data, numbers written next to a "phone" label or in international form). It never guesses a number, never dials, sends no message and reads nothing that is not shown to any visitor. A number can be personal data (a sole trader's mobile): the same responsibilities apply, and rules on phone prospecting (opt-out registers such as Bloctel, prior consent in some countries) differ by country.
Does it need a login or a proxy?
No login. The proxy is included in the price: leave the default setting (the residential proxy is not available). A request the site turns away is retried at once on a new proxy session, up to 10 times on top of the retries (without a proxy, after a pause of 5 seconds, doubled at each retry up to 150 seconds).
Is the data safe to open in Excel or to show on a web page?
Titles and descriptions are the employers' own words, copied as they are, and a phone number starts with +. A text can begin with -, +, = or @: Excel and Google Sheets may read such a cell of a CSV file as a formula or as a number. The Actor leaves the text as it is, so that the JSON and the API give the real value: when you open a CSV, import these columns as text. descriptionHtml is the employer's HTML, not cleaned by the Actor: on a web page, sanitize it, and escape every other field like any text written by a stranger.
Known limitations
- Apply link of a locked job: for many jobs, We Work Remotely shows the employer's apply link only to signed-in job seekers. The Actor uses no account, so
applyUrlis then the site's sign-up or sign-in page, withapplyType=accountorlogin; the employer's own link is given when the job shows it publicly (external,email). - Salary filters in US dollars only:
minSalaryandmaxSalarycompare amounts in USD. A job whose salary is written in another currency is judged on the site's yearly band, with no exchange-rate conversion; without a band, it counts as a job without salary (includeNoSalary). Its own amount and currency are still delivered. - Location filter without the job page: a job limited to a wider area whose listing names no country (
Europe,EMEA,North America) is kept for any place you type, since the listing cannot tell whether your country is in it. TickextractDetails: the job page gives the exact countries accepted, and the filter uses them. - Search, job type and company pages pasted into
startUrlswithoutextractDetails: the posting date is known to the day only, and the keyword, skill and date filters judge the job on what its listing card shows. TickextractDetailsfor the full job. - Jobs taken down are reported only from category pages read in full: never for a category the run could not read, and never by a run that stopped early (
maxItemsreached, timeout, maximum cost) — those jobs stay in memory and the next complete run reports them. - Company contacts: with
extractDetailsalone, a job read before its company's website is known can come without contacts; tickincludeCompanyProfiletoo and every job of a company gets them. onlyNewremembers job ids, not their content: a job whose salary changed is not returned again.- Two runs sharing the same
stateKeyat the same time may both return the same new job.
A run that reaches its timeout stops itself about 45 seconds before it: no new page is asked, what it read is saved and, with onlyNew, remembered, and the run ends Succeeded with "Stopped before the run's timeout". Resurrect it to go on from there, or give the next run a longer timeout (Run options). The whole site, about 400 jobs, takes about 11 minutes even with every job page: the default timeout is far more than enough.
A run the platform stops without warning (out of memory)
- Resurrect it: it goes on from where it stood at most a minute before the stop. What it had read since is read again, and the jobs already saved are skipped: none is delivered or charged twice, and
maxItemsstill counts them. - With
onlyNew, the memory is saved after each write (at most once every 2 seconds): resurrect the stopped run and the jobs it had saved meanwhile join the memory; leave it stopped for good, and the next run may return the jobs of its last 2 seconds once more.
Something doesn't work?
The last line of the log counts the jobs saved, filtered out and no longer on We Work Remotely (removed while the run was reading them), and the requests that failed after every retry. Those requests and the removed jobs are listed, with the reason, in the FAILED_REQUESTS record of the run's key-value store. A run that saved nothing and had failed requests fails, and its last message gives the cause (a company page that does not exist says so, a search with no results too).
If We Work Remotely changes its pages, you are told instead of paying for blank rows. A category page that counts jobs but gives none the Actor can read is an error (listed in FAILED_REQUESTS), never a quiet "No jobs found". If the first 20 jobs read all lack the same field — title, company, posting date, description, category or expiry date (the last three are not checked on the cards of search, job type and company pages, which do not show them), or with extractDetails the apply link or the company's job count — the run saves nothing more, stops and fails, and its last message names the missing field: at most those first jobs are charged. A job that postedAfter / postedBefore drops because it has no date at all counts among those 20. A run of fewer jobs (a scheduled onlyNew run that finds a few new ones, a small Max jobs) is checked at its end, from 5 jobs: its jobs are already saved, and the run fails with the missing field instead of ending green.
🛟 Support
Open an issue in the Issues tab with a link to your run: the run log and the FAILED_REQUESTS record of the key-value store show exactly which URLs failed and why.