# Remote Jobs Scraper (`lergassy/remote-jobs-scraper`) Actor

\[$0.80/1K jobs] Scrape remote jobs from Indeed in 60+ countries — only postings the employer marked Remote. Title, company, website and size, salary as numbers, job type, full description, apply link, recruiter emails. Duplicates removed, no fee per run, no login.

- **URL**: https://apify.com/lergassy/remote-jobs-scraper.md
- **Developed by:** [Matvey](https://apify.com/lergassy) (community)
- **Categories:** Jobs, Lead generation, Agents
- **Stats:** 8 total users, 3 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.56 / 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** returns remote job listings from **Indeed** in 60+ countries — only postings the employer marked as **Remote**. Type job titles or keywords, pick a country, press Start, and get one clean row per job: title, company, company website, size and revenue band, the area the remote job is tied to, **salary as numbers**, job type, posting date, the full description, the apply link, skills, and the **recruiter emails and phones** written in the posting. No login, no API key, no browser: 100 jobs with full descriptions are a single request. Export JSON, CSV or Excel, schedule it, or call it from the API.

> This Actor is a focused entry point for the query "remote jobs". It runs the same engine as **[Jobs API — Indeed, LinkedIn & career sites](https://apify.com/lergassy/jobs-api)**, with Indeed's Remote filter always on. Use Jobs API when you also need on-site or hybrid jobs, LinkedIn, or company career sites.

### What does the remote jobs scraper do?

For each keyword it runs an Indeed search with Indeed's own **Remote** filter switched on — the remote flag the employer sets on the posting — and returns the jobs with their full details. Every row carries `"workplaceType": "remote"` and `"Remote"` among its Indeed attributes.

- **Real remote jobs, not a keyword match.** The filter is Indeed's employer-set Remote attribute, not the word "remote" in the title.
- **One posting, one row.** Indeed often lists the same job under several job keys (the same title, company and text with locations "Remote" and "United States"). Those twins are written and charged once — in our tests 3 of 20 to 63 of 73 results were such duplicates, depending on the keyword.
- **60+ countries.** Remote jobs are listed by the country where the employer hires: `us`, `uk`, `ca`, `au`, `de`, `fr`, `in`, `nl`, `es`, `sg`, `ph`, `br`, `mx` and more.
- **Numbers and company data.** `salaryMin` / `salaryMax` / `salaryCurrency` / `salaryPeriod` as numbers, ISO dates, and the employer's website, size, revenue band and address from Indeed's company profile.
- **Lead-ready.** Emails and phones from the posting text and the company domain from its website or apply link, free.

**Why only Indeed?** We tested LinkedIn's public (logged-out) job search on 06.10.2026: it returns exactly the same jobs with its "Remote" filter, its "On-site" filter, or no filter at all, and only 4 of 50 such "remote" LinkedIn jobs mentioned remote work anywhere in the posting. Selling those as remote jobs would be wrong, so this Actor does not.

### What data does it return?

| Field | Example |
|---|---|
| `source`, `id`, `url`, `applyUrl` | indeed · b8da8f4546d5870f · https://www.indeed.com/viewjob?jk=b8da8f4546d5870f · https://www.gdit.com/careers/job/… |
| `title`, `company`, `companyUrl`, `companyLogo` | Java / Spring Boot Software Developer - REMOTE · General Dynamics Information Technology · https://www.indeed.com/cmp/… · … |
| `companyWebsite`, `companyDomain`, `companySize`, `companyRevenue`, `companyDescription`, `companyAddress` | http://www.gdit.com · gdit.com · 10,000+ · more than $10B (USD) · … · Falls Church, VA |
| `location`, `region`, `country`, `countryCode` | Arizona · AZ · United States · US (the area the remote job is open to, as the employer wrote it) |
| `isRemote`, `workplaceType`, `employmentType`, `jobTypes`, `schedule` | true · remote · fulltime · \["fulltime"] · Monday to Friday |
| `salaryMin`, `salaryMax`, `salaryCurrency`, `salaryPeriod`, `salaryEstimated` | 85093 · 86250 · USD · year · false |
| `postedAt`, `listedAt`, `expired` | 2026-10-05T05:00:00.000Z · 2026-10-06T01:38:47.020Z · false |
| `description`, `descriptionHtml` | full text and HTML |
| `skills`, `attributes` | \["Spring Boot", "Kafka", "GitHub Actions"] · every Indeed tag, including "Remote" |
| `emails`, `phones` | \["careers@trimble.com"] · phone numbers found in the posting |
| `query`, `queryLocation`, `scrapedAt` | software engineer · (empty) · run time |

Salary is filled when the employer publishes it or Indeed shows its own estimate (`salaryEstimated: true`); otherwise null.

### How much does it cost?

**$0.80 per 1,000 remote jobs** ($0.0008 per job row) on the Free plan, down to $0.56 per 1,000 on higher Apify plans. No fee per run or per search. Duplicate postings, error rows and the "nothing matched" explanation row are free.

Example: 5 keywords × 100 jobs = 500 rows = $0.40 on the Free plan.

### How to scrape remote jobs

1. Open the **Input** tab.
2. Type one job title or keyword per line into **🔎 Job titles or keywords** (`customer support`, `python developer`, `bookkeeper`).
3. Pick the **Country**. Leave **Location** empty for remote jobs anywhere in that country, or type a state or city for jobs tied to that area.
4. Optional: **Posted within**, **Job types**, **Jobs per keyword**.
5. Press **Start**, then download the results from the **Output** tab or read them through the API.

An empty API call works too: with no keywords, the Actor returns a demo — 20 remote "software engineer" jobs from Indeed US.

### ⬇️ Input

```json
{
    "keywords": ["customer support", "python developer"],
    "country": "us",
    "location": "",
    "datePosted": "week",
    "jobTypes": ["fulltime"],
    "maxJobsPerQuery": 100
}
```

| Field | Default | What it does |
|---|---|---|
| `keywords` | demo | One Indeed search per line |
| `location` | empty | Optional state or city; empty = the whole country |
| `country` | `us` | Indeed country site (60+) |
| `maxJobsPerQuery` | 100 | Cap per keyword, after duplicates are removed |
| `datePosted` | `any` | `day`, `3days`, `week`, `month` |
| `jobTypes` | all | `fulltime`, `parttime`, `contract`, `temporary`, `internship` |
| `sortBy`, `radius`, `postedAfter` | relevance, 25, empty | Order, distance around a location, fixed start date |
| `startUrls` | empty | Indeed search URLs; the Remote filter is added |
| `includeContacts` | `true` | Emails and phones from the posting, free |
| `maxItems`, `concurrency`, `proxyConfiguration` | 20,000, 5, Apify datacenter | Run cap, parallel searches, proxy |

### ⬆️ Output

One row per job with `"type": "job"`. A free row with `"type": "error"` explains a search that matched nothing or a source that did not answer. Download as JSON, CSV, Excel or XML, or use the API (`/datasets/{id}/items`). A JSON summary of the run (rows, duplicates skipped, requests) is saved as `STATS` in the key-value store.

### Use cases

- **Remote job boards and newsletters**: a daily feed of fresh remote roles by category and country.
- **Job seekers and career coaches**: alerts for remote roles in one field, with salary and company size to sort by.
- **Recruiting and lead generation**: companies hiring remote staff, with their website and the recruiter's email when the posting has one.
- **Labour-market research**: how many remote roles, at what salaries, in which countries and job types.

### Tips

- Leave **Location** empty: remote jobs are usually listed against a country or a state, and a city search narrows them to jobs "remote, but based near …".
- For a daily feed use **Schedules** with `datePosted: "day"` so you pay only for new jobs.
- For on-site or hybrid jobs, LinkedIn, or company career sites, use [Jobs API](https://apify.com/lergassy/jobs-api).

### ❓ FAQ

**Are these all fully remote?** They are the jobs the employer marked as Remote on Indeed. Some remote jobs are open only to people in a given country or state — that is what `location` tells you.

**Is it legal?** It collects job postings that employers publish publicly. Check your own use against the laws that apply to you, especially when you process personal data such as recruiter emails.

**Why fewer rows than I asked for?** Indeed ran out of remote jobs for that keyword and filter, or duplicates were removed. The run summary (`STATS`) shows how many duplicates were skipped.

### Your feedback

Found a bug or a field that looks wrong? Open an issue on the **Issues** tab — we fix reports quickly.

# Actor input Schema

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

One search per line: <code>customer support</code>, <code>python developer</code>, <code>bookkeeper</code>, <code>registered nurse</code>. Every result is a job the employer marked as <b>Remote</b> on Indeed. Empty = a demo search for <code>software engineer</code> (20 jobs).

## `location` (type: `string`):

Optional. Leave empty for remote jobs anywhere in the country below — the usual choice. A state or city (<code>California</code>, <code>Texas</code>, <code>London</code>) keeps remote jobs tied to that area, e.g. "remote, must live in California".

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

Which Indeed country to search: <code>us</code>, <code>uk</code>, <code>ca</code>, <code>au</code>, <code>de</code>, <code>fr</code>, <code>in</code>, <code>nl</code>, <code>es</code>, <code>it</code>, <code>sg</code>, <code>ae</code>, <code>mx</code>, <code>br</code>, <code>ph</code>… (60+ countries). Remote jobs are listed by the country where the employer hires.

## `maxJobsPerQuery` (type: `integer`):

Cap per keyword (empty = 100). Indeed pages 100 jobs per request; the same posting listed twice under different job keys is counted and charged once.

## `datePosted` (type: `string`):

Drop jobs first shown on Indeed earlier than this.

## `jobTypes` (type: `array`):

Empty = all.

## `sortBy` (type: `string`):

Order in which the boards return jobs; the first N are taken.

## `radius` (type: `integer`):

Distance around the location, if you set one.

## `postedAfter` (type: `string`):

<code>YYYY-MM-DD</code>; rows with an older posting date are dropped.

## `startUrls` (type: `array`):

Indeed job-search URLs copied from the browser (<code>https://www.indeed.com/jobs?q=writer\&l=</code>) — each becomes a search, with the Remote filter added. Other sites are ignored.

## `includeContacts` (type: `boolean`):

Recruiter and HR emails and phone numbers written in the job description, plus the company domain from its website or apply link. Free.

## `maxItems` (type: `integer`):

Stop after this many rows.

## `concurrency` (type: `integer`):

How many searches run at once.

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

Apify datacenter proxy (default) works for Indeed. Switch to Residential only if rate-limit error rows appear.

## Actor input object example

```json
{
  "keywords": [
    "customer support",
    "software engineer"
  ],
  "country": "us",
  "maxJobsPerQuery": 25,
  "datePosted": "any",
  "sortBy": "relevance",
  "radius": 25,
  "includeContacts": true,
  "maxItems": 20000,
  "concurrency": 5,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `rows` (type: `string`):

One row per job: source, title, company, company website and size, location, remote/hybrid, job type, salary as numbers, posting date, description, apply link, skills, emails and phones found in the posting.

## `runSummary` (type: `string`):

JSON counters for the run: rows delivered, filtered out, errors and request statistics.

# 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": [
        "customer support",
        "software engineer"
    ],
    "maxJobsPerQuery": 25,
    "includeContacts": true
};

// Run the Actor and wait for it to finish
const run = await client.actor("lergassy/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 = {
    "keywords": [
        "customer support",
        "software engineer",
    ],
    "maxJobsPerQuery": 25,
    "includeContacts": True,
}

# Run the Actor and wait for it to finish
run = client.actor("lergassy/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 '{
  "keywords": [
    "customer support",
    "software engineer"
  ],
  "maxJobsPerQuery": 25,
  "includeContacts": true
}' |
apify call lergassy/remote-jobs-scraper --silent --output-dataset

```

## MCP server setup

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