# Remote Jobs Scraper - Company Career Pages (`firsthand-data/remote-jobs-scraper`) Actor

Remote jobs straight from the career pages of 1,040 remote-first companies on Greenhouse, Ashby, SmartRecruiters and Lever: title, team, location, salary as numbers, dates, links and description. Only-new mode returns new and closed jobs since your last run. No login, no proxy.

- **URL**: https://apify.com/firsthand-data/remote-jobs-scraper.md
- **Developed by:** [Firsthand Data](https://apify.com/firsthand-data) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.60 / 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

## Remote Jobs Scraper - Company Career Pages

Get remote jobs straight from the career pages of **1,040 remote-first companies** on Greenhouse,
Ashby, SmartRecruiters and Lever. These are not reposts from job boards: every job comes from the
company's own hiring system, so it is live, complete and links to the real job page.

Pick the ready-made list or add your own companies, filter by title words and locations, and get
titles, teams, locations, salaries as numbers, dates, links and full descriptions. Turn on
**Only new and closed** and put it on a schedule: every run returns only the remote jobs that
appeared or disappeared since the previous run. You pay only for new jobs.

- ✅ 1,040 remote-first companies, checked by us and refreshed monthly: 22,367 remote jobs on October 20, 2026
- ✅ Remote jobs only: each one is marked remote by the company itself
- ✅ Straight from company career pages: no reposts, no stale copies, direct links to the job
- ✅ Salary parsed into minimum, maximum and currency where the company publishes it
- ✅ New and closed jobs between runs; closed rows are free
- ✅ Official public job board APIs: no login, no API key, no proxies, no browser
- ✅ No personal data: recruiter fields are dropped, emails and phone numbers are removed from descriptions
- 💲 **$2 per 1,000 jobs.** The Apify free plan ($5 of credit every month) covers about 2,500 jobs.

### What can you do with remote job data?

- **Remote job boards and newsletters.** Build a daily feed of new remote jobs with direct links.
  Only-new mode also tells you which jobs closed, so you can expire them.
- **Job seekers and career coaches.** Watch remote roles in your field across a thousand companies
  that hire remotely, the day they are posted.
- **Recruiters and agencies.** See which remote-first companies are hiring and for which roles.
- **Market and salary research.** Compare remote roles, published pay ranges and the countries
  remote-first companies hire from.
- **AI agents.** Let Claude, Cursor or any MCP client answer "which remote-first companies hire
  data engineers in Europe?" with live data.

### How to scrape remote jobs

1. Click **Try for free**. The Apify free plan needs no credit card.
2. In **Ready-made company lists**, pick **Remote-first companies**. Or keep the four prefilled
   companies for a quick test.
3. Optionally add filters: words in the job title (`engineer`, `designer`, `sales`) and locations
   (`Europe`, `United States`, `Canada`).
4. Click **Start**. Download the results as JSON, CSV or Excel, or read them through the Apify API.

The form comes prefilled with four remote-first companies: Tailscale (Greenhouse), PointClickCare
(Lever), Supabase (Ashby) and Software Mind (SmartRecruiters). On October 20, 2026 this run took
7 seconds and returned 198 remote jobs, about $0.40.

### Get only new remote jobs every morning

1. Set **What to return** to **Only new and closed since the last run** and give the watch a
   name, for example `remote-engineering`.
2. Run it once. The first run returns all matching remote jobs as new: this is your starting point.
3. Click **Save as new task**, open **Schedules** and run the task every day (or every hour).
4. In the task's **Integrations** tab, send the results to Slack, email, Zapier, Make or n8n
   (and from there to Google Sheets, Airtable or your job board), or to your own webhook.

Every later run returns only jobs that are new (`changeStatus: "new"`) and jobs that disappeared
from the board (`changeStatus: "closed"`). Closed rows are free, and a quiet day costs nothing.
Use a separate watch name for each feed.

### The remote-first list

| List | Who is in it | Companies | Remote jobs |
|---|---|---|---|
| Remote-first companies | at least half of the open jobs are remote; 5 to 1,000 open jobs | 1,040 | 22,367 on October 20, 2026 |

By hiring system: Ashby 508 companies, Greenhouse 469, SmartRecruiters 59, Lever 4. We rebuild the
list every month from the live job boards, so companies that stop hiring drop out and new
remote-first companies come in.

What the whole list returned on October 20, 2026 (remote jobs, by words in the title and location):

| Remote jobs with... | Jobs |
|---|---|
| engineer, developer, DevOps or SRE in the title | 6,207 |
| data, analyst, machine learning or AI | 3,355 |
| sales, account executive, business development, SDR or BDR | 2,459 |
| healthcare: nurse, therapist, clinician, psychiatrist, counselor | 1,724 |
| marketing, growth, SEO or content | 1,373 |
| product manager, designer or UX | 1,118 |
| support or customer success | 752 |
| finance, accounting or payroll | 601 |
| recruiting, talent, HR or people | 565 |
| location names the United States or the Americas | 10,829 |
| Canada | 1,796 |
| Latin America (Brazil, Mexico, Argentina, Colombia) | 1,457 |
| United Kingdom | 1,290 |
| India | 877 |
| Germany | 674 |
| Europe or EMEA | 484 |
| Asia-Pacific | 402 |
| anywhere or worldwide | 195 |

A job can match more than one row. About half of the jobs (51%) publish a salary range. The whole
list took less than a minute without descriptions; descriptions add time, because on SmartRecruiters
each one is a separate request.

A whole list returns many jobs: running it once without filters costs about $45. To pay
less, add title words or locations, use only-new mode, or set **Maximum cost per run**. Example:
the list with the title word `engineer` returned 6,207 remote jobs (about $12.40). Switch
that to only-new mode and schedule it daily: you get a feed of new remote engineering jobs.

### What data do you get?

| Field | Example | Notes |
|---|---|---|
| `company` | Tailscale | name from the job board |
| `title` | Analytics Engineer, Data | |
| `department`, `team` | Data | where the board gives it |
| `location`, `city`, `region`, `country` | Remote (United States) | `allLocations` keeps every location of the job |
| `workplaceType` | remote | always `remote` in this Actor |
| `employmentType` | full_time | where the board gives it |
| `salaryMin`, `salaryMax`, `salaryCurrency`, `salaryPeriod` | 152000, 190000, USD | from salary fields or the description text |
| `salaryText` | original salary text | |
| `publishedAt`, `updatedAt` | 2026-10-14T18:03:12.000Z | |
| `url`, `applyUrl` | link to the job on the company's job board | |
| `description` | plain text | emails and phone numbers removed |
| `id`, `source`, `board`, `sourceJobId` | greenhouse:tailscale:4512345 | stable id for de-duplication |
| `changeStatus` | new, closed or empty | only in only-new mode |
| `scrapedAt` | time of the run | |

Six rows from the prefilled run on October 20, 2026:

| Company | Title | Location | Salary | Published |
|---|---|---|---|---|
| Tailscale | Analytics Engineer, Data | Remote (United States) | 152,000-190,000 USD | 2026-08-04 |
| Tailscale | Director, APAC Go-to-Market | Remote (Singapore) | | 2026-08-31 |
| PointClickCare | (Canada) Principal ML System Engineer | Remote or Mississauga | 172,000-216,000 CAD | 2026-08-13 |
| Supabase | Product Manager - Strategic Partner Integrations (Bay Area based) | Remote, Bay Area, CA | 200,000-270,000 USD | 2026-08-21 |
| Supabase | AI Platform Engineer | Remote, Global | | 2026-07-31 |
| Software Mind | \[CIS] iOS Software Engineer | Kraków, Lesser Poland Voivodeship, Poland | | 2026-10-20 |

In that run 92 of 198 remote jobs had a salary range. Empty cells are values the company does not
publish. The location is the company's own text: a job can be remote and still name the office or
the country it hires from.

### How much does it cost to scrape remote jobs?

- **$2 per 1,000 jobs** (pay per event). Apify platform usage is included in the price.
- **Free:** closed-job rows, companies without remote jobs, companies that are not found, errors.
- In only-new mode the first run returns all matching jobs (your starting point); later runs return
  only new ones.
- The Apify free plan gives $5 of credit every month: about 2,500 jobs.
- Set **Maximum cost per run** in the run options: the scraper stops before it goes over your limit.

| What you run | Remote jobs | Cost |
|---|---|---|
| The prefilled input (4 companies) | 198 | about $0.40 |
| The remote-first list with the title word `engineer`, once | 6,207 | about $12.40 |
| The same feed every day in only-new mode, if 100 new remote engineering jobs appear a day | about 3,000 a month | about $6 a month |

### Input

#### Companies

Use the ready-made list, your own companies, or both. Three ways to add a company:

| You write | Example | What happens |
|---|---|---|
| `system:board` | `greenhouse:tailscale`, `lever:pointclickcare`, `ashby:supabase`, `smartrecruiters:softwaremind` | read directly |
| Job board link | `https://jobs.ashbyhq.com/supabase` | read directly |
| Company website | `supabase.com` | the scraper looks for a job board link on the website; if there is none, it tries the domain name as a board name and says so in the run summary |

The same company written twice (in any letter case, as different links or also in the list) is
read and charged once. Only remote jobs are returned for every company.

#### Example input

```json
{
  "companyLists": ["remote-first"],
  "companies": ["ashby:supabase"],
  "mode": "changes",
  "watchName": "remote-data-europe",
  "includeKeywords": ["data", "analytics"],
  "excludeKeywords": ["intern"],
  "locations": ["Europe", "United Kingdom", "Germany"],
  "includeDescription": true
}
```

#### Run summary

Each run saves a summary to the key-value store record `OUTPUT`: for every company the system,
board, status (`ok`, `not_found` or `error`), the number of remote jobs and a note when something
needs your attention. A company that fails never stops the run.

### How do you know a job is remote?

The company says so in its own job board: the remote workplace type or remote flag of the job, or
a location such as "Remote - United States" or "Anywhere". Hybrid and on-site jobs are skipped. Many
remote jobs name the countries or time zones they hire from: use **Location contains** to keep only
the regions you need.

### Which job boards are supported?

| System | Board link | Notes |
|---|---|---|
| Greenhouse | `boards.greenhouse.io/{board}`, `job-boards.greenhouse.io/{board}` | salary is often found in the description text |
| Ashby | `jobs.ashbyhq.com/{board}` | unlisted jobs are skipped |
| SmartRecruiters | `jobs.smartrecruiters.com/{board}` | public jobs only; each description is a separate request |
| Lever | `jobs.lever.co/{board}` | salary range where the company publishes it |

Job boards hosted in the EU (`eu.greenhouse.io`, `jobs.eu.lever.co`) are not supported yet.

### Use it with AI agents (MCP)

This scraper works as a tool for AI agents through the Apify MCP server: Claude, Cursor, VS Code,
n8n and other MCP clients. Add this URL as a remote MCP server and sign in to Apify when your
browser opens:

```
https://mcp.apify.com?tools=firsthand-data/remote-jobs-scraper
```

Then ask, for example, "list new remote designer jobs at remote-first companies". Turn off
**Include job description** to keep answers short.

### Integrations

- **Slack and email:** the **Integrations** tab of a run or a saved task.
- **Zapier, Make, n8n:** start on "Run succeeded" and read the dataset; from there send jobs to
  Google Sheets, Airtable, your job board or any other app.
- **Webhooks:** your endpoint gets a call when a run finishes.
- **API:** JavaScript, Python and CLI examples are on the **API** tab of this page.

### Fair use and data quality

- Reads only the official public job board APIs that these systems provide for career pages.
- Keeps to each source's rules: SmartRecruiters at most about 9 requests per second (their limit
  is 10), Lever job pages at most one request per second (their robots.txt), company websites
  only where robots.txt allows.
- No logins, no proxies, no hidden or unlisted jobs.
- No personal data: recruiter names and photos are not collected; emails and phone numbers are
  removed from descriptions.
- Results and the only-new memory stay in your own Apify account. We do not keep copies.
- Not affiliated with Greenhouse, Lever, Ashby or SmartRecruiters. Their names are trademarks of
  their owners.

### FAQ

**Do I need an API key or a proxy?**
No. All four systems publish open jobs through public job board endpoints.

**How is this different from remote job boards?**
Job boards repost jobs, often late and often without salary. This scraper reads the companies'
own career pages, so you get every remote job the moment it is published, with the original
link, salary range and full description.

**Why does a run on the whole list take a few minutes?**
It reads more than a thousand job boards and keeps to each source's rate limit. Descriptions on
SmartRecruiters are separate requests; turn off **Include job description** for faster runs.

**What counts as a new job?**
A job that the watch has not returned before. The same job is never returned as new twice.

**Can I add companies that are not in the list?**
Yes. Add them in **Companies**: only their remote jobs are returned.

**What if I leave Companies empty and pick no list?**
The run does not fail. With title words or locations it searches the whole remote-first list;
without any filter it runs the four sample companies (about 200 jobs), so an empty call through
the API or an AI agent never costs the price of the whole list.

**How fresh is the data?**
Live: the scraper reads each job board at the moment you run it.

### Changelog and support

- **0.1 (October 2026):** first public version: 1,040 remote-first companies on Greenhouse,
  Ashby, SmartRecruiters and Lever, only-new mode, title and location filters.
- We add output fields; we do not rename or remove them. Price changes are announced in advance.
- Questions, bugs or a company you want in the list: open an issue on the **Issues** tab. We
  usually answer within 1-3 days.
- If this scraper saved you time, a short review helps other people find it. Thank you!

# Actor input Schema

## `companyLists` (type: `array`):

Pick "Remote-first companies" to scan all 1,040 companies where at least half of the jobs are remote (about 22,400 remote jobs on Oct 20, 2026). The list is checked by us and refreshed monthly. A whole list returns many jobs: add title filters, use "Only new and closed" or set the maximum cost per run to control the price.

## `companies` (type: `array`):

Add your own companies, one per line: "system:board" (greenhouse:tailscale, lever:pointclickcare, ashby:supabase, smartrecruiters:softwaremind), a job board link (https://jobs.ashbyhq.com/supabase) or the company website (supabase.com). Only their remote jobs are returned.

## `mode` (type: `string`):

All open remote jobs every run, or only remote jobs that are new or closed since the previous run with the same watch name (you pay only for new jobs; closed rows are free).

## `watchName` (type: `string`):

Used only with "Only new and closed": the robot remembers what it already returned under this name. Use a different name for each feed, e.g. "remote-engineering".

## `includeKeywords` (type: `array`):

Keep only jobs whose title contains at least one of these words, e.g. "engineer", "designer", "sales". Case-insensitive. Empty - keep all remote jobs.

## `excludeKeywords` (type: `array`):

Drop jobs whose title contains any of these words, e.g. "intern", "senior".

## `locations` (type: `array`):

Keep only remote jobs whose location text, region or country contains one of these, e.g. "Europe", "United States", "Canada". Many remote jobs name the countries or time zones they hire from.

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

Plain-text description without emails and phone numbers. Turn off for faster runs on big lists (on SmartRecruiters each description is a separate request).

## Actor input object example

```json
{
  "companies": [
    "greenhouse:tailscale",
    "lever:pointclickcare",
    "ashby:supabase",
    "smartrecruiters:softwaremind"
  ],
  "mode": "all",
  "watchName": "default",
  "includeDescription": true
}
```

# Actor output Schema

## `jobs` (type: `string`):

Every remote job returned by this run: company, title, department, location, salary, dates, links, description and change status (new or closed in only-new mode).

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

For every company: job board system, board name, status (ok, not_found or error), number of remote jobs and a note when something needs attention.

# 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 = {
    "companies": [
        "greenhouse:tailscale",
        "lever:pointclickcare",
        "ashby:supabase",
        "smartrecruiters:softwaremind"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("firsthand-data/remote-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 = { "companies": [
        "greenhouse:tailscale",
        "lever:pointclickcare",
        "ashby:supabase",
        "smartrecruiters:softwaremind",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("firsthand-data/remote-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 '{
  "companies": [
    "greenhouse:tailscale",
    "lever:pointclickcare",
    "ashby:supabase",
    "smartrecruiters:softwaremind"
  ]
}' |
apify call firsthand-data/remote-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,firsthand-data/remote-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/vKUBS65ClZpNVYuXR/builds/rTEvrobXEGbJSJ9DP/openapi.json
