We Work Remotely Scraper – Remote Jobs, Keywords & URLs avatar

We Work Remotely Scraper – Remote Jobs, Keywords & URLs

Pricing

from $1.00 / 1,000 results

Go to Apify Store
We Work Remotely Scraper – Remote Jobs, Keywords & URLs

We Work Remotely Scraper – Remote Jobs, Keywords & URLs

Extract current remote job listings from weworkremotely.com. Use keyword search or WWR feed, category, and remote-jobs URLs. Returns clean job rows with title, company, category, region, tags, salary text, description matches, and filtered structured output.

Pricing

from $1.00 / 1,000 results

Rating

0.0

(0)

Developer

Abot API

Abot API

Maintained by Community

Actor stats

0

Bookmarked

4

Total users

0

Monthly active users

2 hours ago

Last modified

Share

We Work Remotely Scraper: Remote Job Listings, Salaries & Apply Links

We Work Remotely Scraper turns We Work Remotely into a clean, structured jobs feed. Search current remote openings by keyword across one or all supported categories, or point it at a specific We Work Remotely feed or category URL, and get back company, title, category, region, salary hints, technologies, seniority and full job descriptions for every listing. Run it once for a snapshot, or turn on Incremental mode to get only new and changed jobs on a recurring schedule, then export the dataset to JSON, CSV or Excel, or pull it straight into your app through the API.

Why This Scraper?

  • Two ways in. Search current listings by keyword across one or all supported categories, or paste a specific We Work Remotely feed or category URL directly.
  • Seven category feeds, one run. Choosing All categories scans every supported category feed and deduplicates jobs by listing URL, for broader coverage than the main feed alone.
  • Filter before you pay. Keep only listings that match a region, a posting age window, a salary hint, a company website, or a minimum description length.
  • Full descriptions on demand. Turn on Include full description fields for cleaned description text and parsed sections (About the company, Responsibilities, Requirements, Benefits); extracted technologies and an inferred seniority level are always computed regardless of this toggle.
  • Built for schedules. Incremental mode tracks one search over time and returns only new and changed jobs on later runs, so a daily monitor never re-bills an unchanged posting.
  • Resume a run that hit its cap. Continue one earlier run that finished but stopped at Max items before reaching every feed, by its run or dataset id; jobs it already collected are skipped rather than re-scraped and re-billed.
  • Optional MCP connector export. Send a compact summary of saved jobs into Notion, Linear, Airtable or Apify after the dataset is written, without changing what stays in the Apify dataset.

Use Cases

  • Recruiting and talent sourcing: run a keyword search across every category to build a daily shortlist of remote openings to reach out against.
  • Lead generation and market tracking: watch which companies are hiring remotely as a signal for sales or investment research.
  • Job board aggregation: mirror We Work Remotely postings, with normalized fields, into your own site, newsletter or app.
  • Compensation and skills research: collect salary hints, seniority levels and extracted technologies across categories to study pay and skill trends.
  • Job alert automation: schedule a keyword search with Incremental mode and forward only newly posted jobs to Slack, email or a chat bot.

Data You Get

Sample shape: values are illustrative placeholders, not from a live record.

FieldExample
jobId"3f9a1c2b7e0d4a58"
title"Senior Software Engineer, Backend (Python)"
companyName"Nimbus Robotics"
category"Back-End Programming"
region"Anywhere in the World"
jobType"Full-Time"
seniorityLevel"Senior"
technologies["Python", "AWS", "PostgreSQL"]
skills["Python", "Django", "AWS"]
salaryText"$140,000 - $170,000"
salaryMin140000
salaryMax170000
postedAt / postedAgeDays"2026-09-20T14:05:00Z" / 8
expiresAt / expiresInDays"2026-10-20T14:05:00Z" / 21
isExpiredfalse
applyUrl / applyUrlIsExternal"https://careers.nimbusrobotics.example/jobs/1234" / true
companyWebsiteUrl"https://nimbusrobotics.example"
canonicalUrl"https://weworkremotely.com/remote-jobs/nimbus-robotics-senior-backend-engineer-example"
descriptionText"We're looking for a senior backend engineer to..." (full text when Include full description fields is on)
descriptionLength3187
descriptionSections{"About the company": "...", "Responsibilities": "..."} (when Include full description fields is on)
externalLinks / externalLinkCount["https://nimbusrobotics.example", "https://careers.nimbusrobotics.example/jobs/1234"] / 2
sourceType / searchKeyword"rss" / "python"
scrapedAt"2026-09-29T08:00:00Z"
changeType / changedFields"NEW" / [] (Incremental mode only)

Each row also carries jobSlug, rawTitle, listingDomain, regionSlug, categorySlug, applicationUrl (a duplicate of applyUrl), externalApplyUrl and applyUrlDomain (set only when the apply link points off We Work Remotely), companyWebsiteDomain, companyLogoUrl, headquarters, locationText, isRemote, isWorldwide, employmentType (a duplicate of jobType), country, state, skillsRaw, skillsCount, skillsSource, salaryCurrency, hasSalary, hasCompanyWebsite, sectionHeadings, aboutCompanyText, responsibilitiesText, requirementsText, benefitsText, sourceUrl, rowType (always "job"), and, in Incremental mode only, firstSeenAt and lastSeenAt.

How to Use

  1. Pick a mode: keyword (search current listings) or url (read a specific We Work Remotely feed or category URL).
  2. In keyword mode, enter your search terms and choose one or more categories, or leave it on All categories for the broadest coverage. In URL mode, paste one or more feed or category URLs.
  3. Add any filters you need (region, posting age, salary, company website, description length) and switch on Include full description fields if you want the full text.
  4. Set Max items to control run size and cost, then click Start.

Keyword search across all categories:

{
"mode": "keyword",
"searchTerms": ["python"],
"categories": ["all"],
"includeDetails": true,
"maxItems": 20
}

Read a specific category feed URL:

{
"mode": "url",
"startUrls": [
{ "url": "https://weworkremotely.com/categories/remote-design-jobs.rss" }
],
"includeDetails": false,
"maxItems": 15
}

Filtered keyword search, engineering roles with a salary and a company site:

{
"mode": "keyword",
"searchTerms": ["engineer"],
"categories": ["programming", "back-end-programming"],
"regions": ["Anywhere in the World"],
"requireSalary": true,
"requireCompanyWebsite": true,
"maxItems": 25
}

Scheduled monitor, only new and changed design jobs:

{
"mode": "keyword",
"searchTerms": ["designer"],
"categories": ["all"],
"incrementalMode": true,
"stateKey": "designer-watch",
"emitExpired": true,
"maxItems": 100000
}

Run it from your code

Python:

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("abotapi/we-work-remotely-jobs-scraper").call(run_input={"mode": "keyword", "searchTerms": ["python"], "categories": ["all"]})
for job in client.dataset(run["defaultDatasetId"]).iterate_items():
print(job["title"], job["companyName"])

JavaScript:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('abotapi/we-work-remotely-jobs-scraper').call({ mode: 'keyword', searchTerms: ['python'], categories: ['all'] });
const { items } = await client.dataset(run.defaultDatasetId).listItems();

Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.

How Max items shapes a run

Max items caps the number of matching rows saved; it does not create more jobs than the selected categories or URLs currently have listed. All categories walks up to seven category feeds one at a time, and the run stops as soon as it has saved Max items rows, so later feeds in the walk may never be fetched. There is no unlimited setting: Max items must be between 1 and 100000. An Incremental run that needs a complete scan (to allow EXPIRED detection, see below) should set Max items high enough that no requested feed is left unfetched.

Resume and recurring updates

Resume from a previous run (resumeFromRunId) continues ONE specific earlier run that finished but stopped at its Max items cap before reaching every feed: paste its run or dataset id and jobs it already collected (matched by jobId) are skipped, so you only pay for the remainder. Since jobs are only pushed once every feed has been walked, a run that crashed or was aborted mid-way has nothing saved to resume from. An id this account cannot read fails the run immediately instead of silently re-scraping everything.

Incremental mode (incrementalMode) is for running the same search again and again on a schedule. Each job is classified NEW, UPDATED (with changedFields), or UNCHANGED (suppressed and not billed unless emitUnchanged is on). EXPIRED is produced only after a run that fetched and fully scanned every requested feed, never after a run that Max items capped mid-walk and never after a run that used Resume from a previous run. REAPPEARED only ever fires for a job that a prior complete, non-resumed scan (with emitExpired on) already marked EXPIRED; a search whose baseline has no EXPIRED job yet will never produce a REAPPEARED row. stateKey names or shares the stored state; leave it empty and the actor derives one from your mode, search terms or URLs, and every filter, so two different setups never mix state. With Incremental mode off, output is exactly as before.

Send results into your apps (MCP connectors)

Optionally pipe the scraped jobs into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape: the Apify dataset is never changed.

What gets written to the connector: a condensed, human-readable summary of each job, not the full JSON. Each job becomes one entry with a title and its key fields flattened to plain text. The complete record always stays in the Apify dataset.

  1. Authorize a connector once under Apify → Settings → Integrations (Notion, Linear, Airtable, or Apify).
  2. Select it in the "Pipe results into your apps" input field. (If the picker is empty, you haven't authorized a connector yet.)
  3. For Notion, also set notionParentPageUrl to the page where job pages should be created.

The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.

Input Parameters

ParameterTypeDefaultDescription
modestringkeywordkeyword (search current listings) or url (read specific feed/category URLs).
startUrlsarrayno default (prefill: 3 sample We Work Remotely URLs)Feed, category, category RSS, or main remote-jobs URLs to read in url mode.
searchTermsarrayno default (prefill: ["python"])Terms matched against title, company, category, region, tags and description text (keyword mode).
categoriesarray["all"]Restrict keyword search to selected categories; leave on All categories to scan every supported category feed.
regionsarrayno default (empty; no region filter)Keep listings whose region contains one of these values, such as Anywhere in the World or Europe.
includeDetailsbooleantrueInclude full description HTML/text, parsed sections, and section-derived fields in each row.
maxItemsinteger20Maximum matching job rows to save (1 to 100000); a cap, not a guarantee.
postedWithinDaysintegerno default (empty; no age filter)Keep only jobs posted within this many days.
requireSalarybooleanfalseKeep only rows where a salary hint was found in the listing text.
requireCompanyWebsitebooleanfalseKeep only rows with a company website URL.
requireApplyUrlbooleanfalseKeep only rows with an apply URL. Every row already carries one, since it falls back to the We Work Remotely listing link when no separate apply link is found, so this filter currently changes nothing.
minDescriptionLengthintegerno default (empty; no length filter)Keep only rows whose full cleaned description text has at least this many characters, measured on the complete text even when includeDetails is off.
resumeFromRunIdstringno default (empty)Continue ONE specific interrupted run by its run or dataset id; already-collected jobs are skipped.
incrementalModebooleanfalseTurn on for recurring monitoring: later runs return only new and changed jobs.
stateKeystringno default (empty; auto-derived from mode/search/filters)Name or share an Incremental mode monitoring campaign.
emitUnchangedbooleanfalseAlso return (and bill) jobs that have not changed since the last run, marked UNCHANGED.
emitExpiredbooleanfalseAlso return (and bill) jobs that were tracked before and are no longer found, marked EXPIRED. Only produced after a complete, non-resumed scan.
proxyobjectno default (prefill: Apify Proxy on, no groups)Connection settings; uses Apify Proxy with the standard datacenter pool by default.
mcpConnectorsarrayno default (empty; skip export)Optional: send a summary of each saved job to apps you authorized under Integrations.
notionParentPageUrlstringno default (empty)Notion connector only: page under which job pages are created.
maxNotifyListingsinteger50Cap on how many jobs are written to each selected connector per run.

Output Example

Sample shape: values are illustrative placeholders, not from a live record.

{
"rowType": "job",
"jobId": "3f9a1c2b7e0d4a58",
"jobSlug": "nimbus-robotics-senior-backend-engineer-example",
"title": "Senior Software Engineer, Backend (Python)",
"rawTitle": "Nimbus Robotics: Senior Software Engineer, Backend (Python)",
"companyName": "Nimbus Robotics",
"url": "https://weworkremotely.com/remote-jobs/nimbus-robotics-senior-backend-engineer-example",
"canonicalUrl": "https://weworkremotely.com/remote-jobs/nimbus-robotics-senior-backend-engineer-example",
"applyUrl": "https://careers.nimbusrobotics.example/jobs/1234",
"applyUrlIsExternal": true,
"companyWebsiteUrl": "https://nimbusrobotics.example",
"region": "Anywhere in the World",
"category": "Back-End Programming",
"jobType": "Full-Time",
"skills": ["Python", "Django", "AWS"],
"technologies": ["Python", "AWS", "PostgreSQL"],
"seniorityLevel": "Senior",
"salaryText": "$140,000 - $170,000",
"salaryMin": 140000,
"salaryMax": 170000,
"salaryCurrency": "USD",
"postedAt": "2026-09-20T14:05:00Z",
"postedAgeDays": 8,
"expiresAt": "2026-10-20T14:05:00Z",
"expiresInDays": 21,
"isExpired": false,
"descriptionText": "We're looking for a senior backend engineer to own our core payments API...",
"descriptionLength": 3187,
"descriptionSections": { "About the company": "Nimbus Robotics builds...", "Responsibilities": "Own our core payments API..." },
"externalLinks": ["https://nimbusrobotics.example", "https://careers.nimbusrobotics.example/jobs/1234"],
"sourceType": "rss",
"searchKeyword": "python",
"scrapedAt": "2026-09-29T08:00:00Z"
}

Plan Requirement

This actor uses pay-per-event pricing: a small one-time fee when a run starts, a per-row fee for every job saved to the dataset, and an extra per-row fee only for runs with Include full description fields turned on. That extra fee does not add network requests: the full description is already part of the fetched feed data, the toggle only decides whether it is kept in the output. The Pricing tab on the actor page shows the current rates. Apify Proxy with the standard datacenter pool is used by default; adjust the Connection settings only if your run environment needs a different route.

FAQ

How much does it cost?

You pay a small one-time fee when a run starts, a per-row fee for every job returned, and an extra per-row fee only when Include full description fields is switched on. The Pricing tab shows the current rates. Use Max items to cap the size, and cost, of any run.

This actor collects only publicly available job listing data. You are responsible for how you use it: follow We Work Remotely's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution.

Can I get only new or changed jobs on a schedule?

Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then returns only new and updated jobs by default; jobs that have not changed are suppressed and not billed unless you turn on Emit unchanged, and expired jobs only appear once you also turn on Emit expired, with reappeared jobs only possible after that on a later run.

Why can't I paste a specific job posting URL?

URL mode reads We Work Remotely feed, category and category RSS URLs, not individual job listing pages: the actor always works from a feed's current list of jobs, never a single job's detail page. To track one specific posting, use Keyword search with a term unique to that listing, such as the company name, or watch the category it belongs to with Incremental mode.

Why did my run fail instead of returning an empty dataset?

A run fails cleanly with a clear message in two cases: Resume from a previous run points at an id this account cannot read, or Resume from a previous run is combined with Incremental mode on a search that already has saved state. Any other problem, an invalid mode, no search terms or URLs given, a URL mode input with no recognizable feed/category/remote-jobs URL, or a network or feed error while reading a page, crashes the run instead, since records are only pushed once every feed has been walked. If your search or filters simply match no current listings, the run completes normally with an empty dataset.

Can I use it with AI agents or MCP?

Yes. Call it from any Apify integration or MCP client, and use the connector field to push a summary of each saved job into Notion, Linear or Airtable.

🔗 Want more jobs data?

Pair this actor with these related scrapers from the same team:

💼 RemoteOK Jobs Scraper
Scrape RemoteOK jobs by keyword or job URL. Extract title, company, location, remote...
💼 Cwjobs UK
From $1/1k. Scrape tech and IT jobs from CWJobs.co.uk into clean, structured data. Search...
💼 Jora Jobs Scraper
Scrape Jora.com job listings across supported countries by keyword, filters, or URL...
💼 Jobs.cz
Scrape Czech job listings from Jobs.cz. Search builder (keyword, location, field, salary...
💼 Gupy Jobs Scraper
Scrape public jobs from Gupy.io by keyword, state, city, workplace type, job type...
💼 Wellfound Jobs Scraper
Scrape startup jobs from Wellfound.com by keyword, location, role, or remote status...

👉 Browse all abotapi scrapers

💬 Support & custom scrapers

  • 🐞 Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
  • 🛠️ Need another site, extra fields or a private build? Email abotapi@proton.me or message Telegram @abotapi.
  • ⭐ Enjoying it? A quick review on the actor page helps other users find it.