# We Work Remotely Jobs: Full Descriptions (`deepmine/we-work-remotely-jobs-scraper`) Actor

Search We Work Remotely (WeWorkRemotely, WWR) jobs by keyword or category: title, company, job type, WWR category, posted and expiry dates, apply link, company website when listed and the full description in every row. Filter by country, date, job type and category. For job boards and newsletters.

- **URL**: https://apify.com/deepmine/we-work-remotely-jobs-scraper.md
- **Developed by:** [DeepMine](https://apify.com/deepmine) (community)
- **Categories:** Jobs
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.80 / 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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## We Work Remotely Jobs: Full Descriptions

We Work Remotely scraper: type a keyword like engineer or marketing and get WeWorkRemotely (WWR) jobs with title, company, WWR category, job type, posted and expiry dates, apply link and the full description in every row, newest first.

| 💼 Title | 🏢 Company | 📂 WWR Category | 🕒 Job Type | 📍 Location | 📅 Posted |
|---|---|---|---|---|---|
| Senior .NET Full-stack Developer | Lemon.io | Full-Stack Programming | Full-time | Anywhere | 2026-10-08 |
| IT Infrastructure Engineer | BlueGeko | DevOps and Sysadmin | Full-time | Anywhere | 2026-10-08 |
| Senior Product Engineer | Semaphore | Product | Contract | Anywhere | 2026-10-06 |

<sub>Collected 2026-10-08.</sub>

**$0.99 per 1,000 jobs** on the Starter plan ($1.18 Free, $0.89 Scale, $0.80 Business). The prefilled run (up to 100 jobs: 50 engineer and 50 marketing jobs of the last 14 days) costs about $0.10.

It reads We Work Remotely's public category feeds at run time: no login, no browser, no cookies. The full description comes in every row at the same price (no extra detail-page charge). The prefilled run on 2026-10-08 delivered 94 jobs (47 engineer, 47 marketing). On the Apify platform it took 8 seconds, and 64 seconds on a run when We Work Remotely's feeds answered slowly (the rows come once the feeds are read). 26 of the 94 named the company's website and 17 gave a contact email in the description. We Work Remotely's feeds carry no pay, level or time zones, so those fields stay empty and the views leave them out.

Want more boards in one list? [Remote Jobs Aggregator](https://apify.com/deepmine/remote-jobs-aggregator) searches We Work Remotely, Himalayas, Remote OK, Jobicy, Relomote, Arbeitnow and Working Nomads at once.

### What you can do with it

- **Feed a job board, newsletter or Slack channel** with fresh WWR jobs: schedule a daily run with `postedWithinDays` set to 2, or add an Apify webhook to send each finished run to your own system.
- **Watch one WWR category**: set `categories` (Software Development, Design, Marketing, Customer Support...) and leave `keywords` empty for every new job in it.
- **Reach hiring companies**: `companyWebsite` and `contactEmail` come with the jobs that list them; `findContactEmails` looks for an email on the company's own site.

### Input

```json
{
  "keywords": ["engineer", "marketing"],
  "postedWithinDays": 14,
  "maxJobsPerKeyword": 50,
  "employmentTypes": ["Full-time"]
}
```

| Field | What it does |
|---|---|
| `keywords` | What to search for, one per line: a skill, role or tool (engineer, marketing, python). A job matches when every word is in its title, company, or We Work Remotely's category and skills; a skill or tool also matches in the description. Title matches go first. An empty list gives the latest We Work Remotely jobs of every kind. |
| `categories` | Optional. Keep only jobs in these categories (the boards' own categories, in common words). Leave empty for every category. |
| `country` | Optional. A country you live in (United States, Germany, India, Brazil...): keeps the jobs open to its residents, including jobs open worldwide and jobs for its region (Europe, LATAM, APAC, North America). Type Worldwide for only the jobs open to anyone, anywhere. Leave empty for every job. |
| `postedWithinDays` | Keep only jobs posted in the last N days; older ones cost nothing. 0 means any date. Handy for a daily or weekly scheduled run. |
| `maxJobsPerKeyword` | The jobs to keep per keyword: the best matches (title matches first), newest first. You pay per job, so this caps the cost per keyword. 0 means every job. Default 100. |
| `boards` | Fixed to `weworkremotely` (hidden in the form). |
| `employmentTypes` | More filters. Optional. Keep only these job types. A job whose board doesn't give its type (and whose title doesn't say, e.g. 'Contract') is left out. Leave empty for every type. |
| `seniority` | More filters. Optional. Keep only these levels, read from a clear title word (Senior, Lead, Junior, Director, VP); jobs with none are left out. Leave empty for every level. |
| `minSalary` | More filters. Optional. Keep only jobs that list a US-dollar salary whose top of range is at least this per year. We Work Remotely rarely lists pay, so most jobs are left out. 0 means no salary filter. |
| `timezone` | More filters. Hidden in this form: We Work Remotely lists no time zones (a value keeps only jobs open worldwide). |
| `maxResults` | Advanced. Stop after this many jobs in total. You pay per job, so this caps the run's cost. |
| `includeDescription` | Advanced. The full job description as plain text. Same price either way; turn it off for smaller rows. |
| `includeDescriptionHtml` | Advanced. Also the board's description as HTML (links and lists kept), in descriptionHtml. Same price; rows get about twice as big. |
| `findContactEmails` | Advanced. For jobs whose description gives no email, look for one on the company's own website (the one We Work Remotely lists, or one confirmed from the company's name). Charged per job that gets an email this way ($). Slower. |
| `proxyConfiguration` | Advanced. Apify Proxy (datacenter) by default; the boards' feeds are public, so it only spreads the requests over several IPs. Residential and SERP proxies are replaced with datacenter. Turn it off to connect directly. |

### Output

One row per job, newest first, as soon as the feeds answer. A job that several keywords find comes once, under the first keyword that found it.

Two datasets, both with the same rows:

- **💼 All Jobs** (default dataset). Views: **💻 WWR Jobs** (💼 Title, 🏢 Company, 📂 Board Category, 🕒 Job Type, 📍 Location, 📅 Posted, ⌛ Expires, 📧 Contact Email, 🌐 Website, 📝 Apply, 🔗 Job Page), then **📊 Overview**, **📝 Details** and **📇 Contacts**.
- **💰 With Salary**: the delivered jobs that publish a salary, at no extra charge. It stays empty here: We Work Remotely's feeds carry no pay.

#### Output fields

In row order:

- `companyLogo`: the company's logo, for the jobs that show one (about 1 in 5 on We Work Remotely).
- `title`: job title.
- `company`: company name.
- `location`: where a hire may live, in short: `Anywhere`, `United States`, `Europe, United Kingdom`.
- `isWorldwide`: `true` when anyone anywhere can apply, `false` when the board names places.
- `employmentType`: `Full-time`, `Part-time`, `Contract`, `Temporary`, `Internship` or `Volunteer`.
- `seniority`: empty: We Work Remotely gives no level (the `seniority` filter reads a clear title word instead).
- `category`: the board's category in common words (Software Development, Design, Marketing...).
- `salary`: published pay. Empty: We Work Remotely's feeds carry no pay (same for the four salary fields below).
- `salaryMin`: the lowest pay in the range, as a number.
- `salaryMax`: the highest pay in the range, as a number.
- `salaryCurrency`: ISO currency code, e.g. `USD`.
- `salaryPeriod`: `year`, `month`, `2 weeks`, `week`, `day` or `hour`.
- `postedAt`: when the job was published, in UTC (`2026-10-08T14:36:55Z`).
- `expiresAt`: when the board takes the listing down, in UTC.
- `jobUrl`: the job's page on the board.
- `applyUrl`: where to apply: the employer's own link when the description gives one, else the board's page.
- `contactEmail`: a contact email the description gives (or, with `findContactEmails`, the company's website).
- `contactEmailSource`: the page the email was found on.
- `companyWebsite`: the company's own website, when the board lists it.
- `companyUrl`: the company's page on the board (empty: We Work Remotely has none).
- `locations`: every country or region the board lists.
- `timezones`: UTC offsets a hire must work in (empty: We Work Remotely lists none).
- `tags`: skills and labels the board gives the job.
- `boardCategory`: the board's own category name as it prints it.
- `description`: the full job description as plain text (on by default).
- `descriptionHtml`: the description as HTML. Only with `includeDescriptionHtml`.
- `sources`: the board that lists the job.
- `sourceUrls`: the job's page on that board.
- `jobId`: the job's id on the board.
- `keywords`: your keywords that found the job. Empty for a run without keywords.
- `scrapedAt`: when this run read the job (UTC).

Example row (description shortened):

```json
{
  "companyLogo": "https://wwr-pro.s3.amazonaws.com/logos/0171/6546/logo.gif",
  "title": "Senior .NET Full-stack Developer",
  "company": "Lemon.io",
  "location": "Anywhere",
  "isWorldwide": true,
  "employmentType": "Full-time",
  "seniority": null,
  "category": "Software Development",
  "salary": null,
  "salaryMin": null,
  "salaryMax": null,
  "salaryCurrency": null,
  "salaryPeriod": null,
  "postedAt": "2026-10-08T11:41:36Z",
  "expiresAt": "2026-11-07T11:41:36Z",
  "jobUrl": "https://weworkremotely.com/remote-jobs/lemon-io-senior-net-full-stack-developer-2",
  "applyUrl": "https://weworkremotely.com/remote-jobs/lemon-io-senior-net-full-stack-developer-2",
  "contactEmail": null,
  "contactEmailSource": null,
  "companyWebsite": "https://lemon.io",
  "companyUrl": null,
  "locations": null,
  "timezones": null,
  "tags": [
    "AngularJS",
    "React",
    "Vue.js",
    "Engineer",
    "Developer",
    "Full Stack Dev",
    "Full Time",
    "English",
    "C#",
    "TypeScript"
  ],
  "boardCategory": "Full-Stack Programming",
  "description": "Headquarters: New York, NY\n\nURL: https://lemon.io\n\nAre you a talented Senior Developer looking for a remote job that lets you show your skil ...",
  "descriptionHtml": null,
  "sources": [
    "We Work Remotely"
  ],
  "sourceUrls": [
    "https://weworkremotely.com/remote-jobs/lemon-io-senior-net-full-stack-developer-2"
  ],
  "jobId": "lemon-io-senior-net-full-stack-developer-2",
  "keywords": [
    "engineer"
  ],
  "scrapedAt": "2026-10-08T15:10:47Z"
}
```

The run's **🧾 Run summary** (the OUTPUT record in the key-value store) shows how many jobs the feeds sent and matched per keyword, plus any error.

### Credit the boards

We Work Remotely shares its jobs on the condition that you credit it: keep each job's `sourceUrls` (a link back to the original posting) and name the board from `sources` when you show the jobs to others. Don't resubmit the jobs to aggregators such as Google Jobs as your own postings.

### When something goes wrong

- If We Work Remotely doesn't answer after several retries on fresh IPs, or a feed comes back cut off or in a format we can't read, the run ends as **failed** with the reason in the status message and the run summary, so you notice.
- If We Work Remotely asks us to slow down (HTTP 429), the run waits as long as it asks and tries again.
- A keyword with no We Work Remotely job gives a clean empty result and a status message saying so.
- When `maxResults` or your spending limit is reached, the run stops after delivering every job the limit pays for; you pay only for the jobs delivered.

### Pricing

You pay per job delivered: $0.99 per 1,000 jobs on the Starter plan ($1.18 Free, $0.89 Scale, $0.80 Business). The full description, apply link and the emails descriptions give are included at the same price. No start fee. With `findContactEmails` on, a job that gets its contact email from the company's website adds $0.98 per 1,000 such jobs. Requests, retries and jobs left out by your filters cost nothing.

Examples: the prefilled run (up to 100 jobs) about $0.10; 1,000 jobs $0.99.

### FAQ

**How many jobs does a run reach?** Everything in We Work Remotely's ten category feeds, about 300 open jobs. `maxJobsPerKeyword` keeps the best matches (title matches first), and `maxResults` caps the whole run.

**How fresh is the data?** Each run reads the feeds at run time, so a job comes in as soon as We Work Remotely lists it.

**Can I get new jobs every day?** Yes: save your input as a task, schedule it daily and set `postedWithinDays` to 2. A job two runs find comes in both; dedupe on `jobUrl`.

**Does it collect personal data?** Rows hold jobs and companies, no recruiter profiles. `contactEmail` is the address a posting or the company's website publishes; use it within the privacy and anti-spam rules that apply to you.

### Feedback

Missing a field or a filter? Open an issue on the Issues tab and we'll look at it. If the data helped you, a short review on this page helps other people find it.

# Actor input Schema

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

What to search We Work Remotely for, one keyword per line: a skill, role or tool (python, product designer, customer support). Leave the list empty for the latest jobs of every kind. You pay per job delivered.

## `categories` (type: `array`):

Optional. Keep only jobs in these categories (the boards' own categories, in common words). Leave empty for every category.

## `country` (type: `string`):

Optional. A country you live in (United States, Germany, India, Brazil...): keeps the jobs open to its residents, including jobs open worldwide and jobs for its region (Europe, LATAM, APAC, North America). Type Worldwide for only the jobs open to anyone, anywhere. Leave empty for every job.

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

Keep only jobs posted in the last N days; older ones cost nothing. 0 means any date. Handy for a daily or weekly scheduled run.

## `maxJobsPerKeyword` (type: `integer`):

The jobs to keep per keyword: the best matches (title matches first), newest first. You pay per job, so this caps the cost per keyword. 0 means every job. Default 100.

## `boards` (type: `array`):

Fixed to We Work Remotely in this Actor. To search seven remote job boards at once, use Remote Jobs Aggregator.

## `employmentTypes` (type: `array`):

Optional. Keep only these job types. A job whose board doesn't give its type (and whose title doesn't say, e.g. 'Contract') is left out. Leave empty for every type.

## `seniority` (type: `array`):

Optional. Keep only these levels, read from a clear title word (Senior, Lead, Junior, Director, VP); jobs with none are left out. Leave empty for every level.

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

Optional. Keep only jobs that list a US-dollar salary whose top of range is at least this per year. We Work Remotely rarely lists pay, so most jobs are left out. 0 means no salary filter.

## `timezone` (type: `string`):

Optional UTC offset you work in, e.g. UTC-5, UTC+1, UTC+5:30. Keeps Himalayas jobs that accept it (the only board that lists time zones) and, from the other boards, only jobs open worldwide.

## `maxResults` (type: `integer`):

Stop after this many jobs in total. You pay per job, so this caps the run's cost.

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

The full job description as plain text. Same price either way; turn it off for smaller rows.

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

Also the board's description as HTML (links and lists kept), in descriptionHtml. Same price; rows get about twice as big.

## `findContactEmails` (type: `boolean`):

For jobs whose description gives no email, look for one on the company's own website (the one We Work Remotely lists, or one confirmed from the company's name). Charged per job that gets an email this way ($). Slower.

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

Apify Proxy (datacenter) by default; the boards' feeds are public, so it only spreads the requests over several IPs. Residential and SERP proxies are replaced with datacenter. Turn it off to connect directly.

## Actor input object example

```json
{
  "keywords": [
    "engineer",
    "marketing"
  ],
  "postedWithinDays": 14,
  "maxJobsPerKeyword": 50,
  "boards": [
    "weworkremotely"
  ],
  "minSalary": 0,
  "maxResults": 1000,
  "includeDescription": true,
  "includeDescriptionHtml": false,
  "findContactEmails": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

No description

## `withSalaryUrl` (type: `string`):

No description

## `summary` (type: `string`):

No description

# 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 = {
    "keywords": [
        "engineer",
        "marketing"
    ],
    "postedWithinDays": 14,
    "maxJobsPerKeyword": 50,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("deepmine/we-work-remotely-jobs-scraper").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 = {
    "keywords": [
        "engineer",
        "marketing",
    ],
    "postedWithinDays": 14,
    "maxJobsPerKeyword": 50,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("deepmine/we-work-remotely-jobs-scraper").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 '{
  "keywords": [
    "engineer",
    "marketing"
  ],
  "postedWithinDays": 14,
  "maxJobsPerKeyword": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call deepmine/we-work-remotely-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,deepmine/we-work-remotely-jobs-scraper"
        }
    }
}
```

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/TgS1YLJiN0cc4Q4aj/builds/Uhrbntnvqpm5npegE/openapi.json
