# Indeed Remote Jobs Scraper (`schnellscrapers/indeed-remote-jobs`) Actor

Scrape Indeed remote job listings posted in the last 3 days, with job title, company, salary ranges, location, job type, posted timestamp, snippet, and apply URL. Search multiple keywords and countries, require disclosed salary, and sort newest first. Pay per saved job; no login required.

- **URL**: https://apify.com/schnellscrapers/indeed-remote-jobs.md
- **Developed by:** [Nate Schnell](https://apify.com/schnellscrapers) (community)
- **Categories:** Jobs, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$3.49 / 1,000 remote jobs

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

### What does Indeed Remote Jobs Scraper do?

Indeed Remote Jobs Scraper collects fresh remote job listings from Indeed and returns one clean dataset record per accepted job. It defaults to jobs posted within the last 3 days, sorts by date, removes duplicates, and keeps fully remote roles before they reach the dataset. Use it for recruiter sourcing, scheduled job alerts, remote job boards, or hiring-market snapshots.

### What data can you extract from Indeed?

- Job identity — `jobKey`, `title`, `viewJobUrl`, `postedRelative`, `postedAt`, `scrapedAt`
- Company data — `company`, `companyIndeedUrl`, `companyRating`, `companyReviewCount`
- Compensation — `salary.min`, `salary.max`, `salary.type`, `salary.currency`, `salary.text`
- Remote location — `location`, `city`, `state`, `country`, `remote`, `remoteWorkType`
- Hiring details — `jobTypes`, `snippet`, `indeedApplyable`, `thirdPartyApplyUrl`, `urgentlyHiring`, `sponsored`
- Optional enrichment — best-effort `description` and `descriptionHTML` when full descriptions are enabled; a blocked detail page leaves these fields null while preserving the job record

The `remoteWorkType` field distinguishes `REMOTE_ALWAYS`, `HYBRID`, `IN_PERSON`, and `UNKNOWN`. Hybrid roles are excluded by default; turn on Include hybrid jobs when a broader distributed-work feed is useful.

### How to use Indeed Remote Jobs Scraper

1. Open Indeed Remote Jobs Scraper and add a keyword such as `data engineer`, `customer success`, or `registered nurse`.
2. Add a location, country code, and freshness window. Use the JSON Searches input to run several keyword/location combinations at once.
3. Keep the default remote-only mode, or enable Include hybrid jobs. Enable Require salary when the feed is for compensation research or qualified recruiter leads.
4. Set Maximum jobs and Pages per search to keep the run predictable, then click Run.
5. Download the completed dataset as JSON, CSV, or Excel, or read it through the Apify API. Detail-page enrichment is best effort because Indeed can challenge individual job pages.

### How much does it cost?

Indeed Remote Jobs Scraper uses pay-per-event pricing from $1.49 / 1,000 saved remote job records. A saved record is a unique job that passes the remote and optional salary filters. Set Maximum jobs to control the record budget, and leave full descriptions off when you only need search-card data. Apify account credits can cover test runs; check the Pricing tab for the current rate before a production schedule.

### Input

Use `searches` for multiple keyword and location combinations, or use the single-search shortcut fields. Every search is sent to Indeed with remote filtering enabled and defaults to a 3-day freshness window. The actor accepts Indeed country codes such as `us`, `ca`, `uk`, `de`, and `au`.

```json
{
  "searches": [
    { "query": "software engineer", "location": "Remote", "country": "us", "postedWithinDays": 3 },
    { "query": "data analyst", "location": "Canada", "country": "ca", "postedWithinDays": 7 }
  ],
  "maxItems": 100,
  "maxPagesPerSearch": 5,
  "requireSalary": false,
  "includeFullDescription": false
}
```

Residential Apify Proxy is enabled by default because Indeed may challenge direct or datacenter requests. A deliberately small `maxItems` value is a good first run.

### Output

Each dataset item is one accepted remote job. Salary values are nested so downstream systems can use numeric ranges without reparsing display text.

```json
{
  "jobKey": "a1b2c3d4e5f6",
  "title": "Senior Software Engineer",
  "company": "Example Labs",
  "location": "Remote",
  "remote": true,
  "remoteWorkType": "REMOTE_ALWAYS",
  "salary": { "min": 140000, "max": 180000, "type": "YEARLY", "currency": "USD", "text": "$140,000–$180,000 a year" },
  "jobTypes": ["Full-time"],
  "postedAt": "2026-08-08T12:00:00.000Z",
  "viewJobUrl": "https://www.indeed.com/viewjob?jk=a1b2c3d4e5f6",
  "thirdPartyApplyUrl": "https://example.com/careers/roles/a1b2c3d4e5f6"
}
```

### Integrations

Schedule Indeed Remote Jobs Scraper with Apify Scheduler, send new records through [Make](https://www.make.com/en/integrations/apify), [n8n](https://n8n.io/integrations/apify/), or webhooks, and pull the dataset from Python or Node with the [Apify API](https://docs.apify.com/api/v2). The flat JSON output also fits job boards, Airtable, spreadsheets, and ATS import steps.

### Related actors

- [Indeed Jobs Scraper](https://apify.com/schnellscrapers/indeed-jobs-scraper) — broad Indeed fields and optional full descriptions when the remote-only slice is too narrow.
- [RemoteOK Jobs Scraper](https://apify.com/schnellscrapers/remoteok-jobs-scraper) — add a second remote-first job source to a hiring feed.
- [Ashby Jobs Scraper](https://apify.com/schnellscrapers/ashby-jobs-scraper) — collect structured roles directly from Ashby-hosted company boards.

### FAQ

#### How does Indeed Remote Jobs Scraper work?

It loads Indeed search pages using the filters in your input, reads the structured job-card data returned for each page, normalizes fields such as salary and posted date, and writes only unique records that match the remote-feed filters.

#### Can I use Indeed Remote Jobs Scraper as an API?

Yes. Start a run through the Apify API, then read the run's default dataset. You can also schedule runs and connect dataset events to webhooks or automation tools.

#### Can I use Indeed Remote Jobs Scraper in Python or Node.js?

Yes. Use the official `apify-client` package to start a run and read its dataset.

```js
import { ApifyClient } from "apify-client";

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor("schnellscrapers/indeed-remote-jobs").call({
  query: "software engineer",
  location: "Remote",
  maxItems: 20
});
```

#### Does every job include a salary?

No. Indeed only exposes pay when the employer or Indeed provides it. Enable Require salary to keep records with a numeric minimum or maximum.

#### Can I include hybrid roles?

Yes. Enable Include hybrid jobs. Fully remote roles are the default because this actor is designed for remote hiring alerts.

#### Is it legal to scrape Indeed?

This actor reads public job listings and does not submit applications. Review Indeed's current terms, applicable data-protection rules, and your intended use before running it commercially; the user is responsible for that assessment.

#### What does this actor access?

It accesses public Indeed search and job-detail pages. No Indeed login or user API key is required, but a residential Apify Proxy is recommended for reliable access.

### Your feedback

If a source layout changes or you need another freshness filter, use the Issues tab on the actor page to report it and request the exact input or output you need.

# Actor input Schema

## `searches` (type: `array`):

Run one or more remote Indeed searches. Each entry accepts `query`, `location`, `country`, `postedWithinDays` (1–14), `jobType`, `radius`, and `sort`. Remote filtering and newest-first ordering are applied automatically.

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

Optionally paste fully formed Indeed search URLs. The actor keeps the keyword and location, then applies the remote and freshness filters for this feed.

## `position` (type: `string`):

Single-search shortcut for a job title, skill, or company (for example, `data analyst`). Used only when Searches and Indeed search URLs are empty.

## `query` (type: `string`):

Alias for Search keyword. Enter a role, skill, or employer name when running one remote search.

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

City, state, ZIP code, or `Remote`. Leave blank for a country-wide remote search.

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

Two-letter Indeed country code such as `us`, `ca`, `uk`, `de`, or `au`.

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

Keep jobs posted within this many days. Defaults to 3 so scheduled runs produce a fresh lead feed; use 1 for daily alerts.

## `fromDays` (type: `integer`):

Compatibility alias for Freshness window. Use `7` for a one-week remote-job feed.

## `jobType` (type: `string`):

Restrict the single-search shortcut to one employment type: fulltime, parttime, contract, temporary, internship, or permanent.

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

Distance from Location in miles for US searches or the local unit used by other Indeed domains. Remote jobs still use Indeed's location matching.

## `sort` (type: `string`):

Use `date` for newest-first hiring alerts or `relevance` for Indeed's ranking. The default is `date`.

## `includeHybrid` (type: `boolean`):

Include hybrid roles alongside fully remote roles. Leave off for a strict remote-only feed.

## `requireSalary` (type: `boolean`):

Keep only listings where Indeed provides a numeric salary minimum or maximum. Jobs without disclosed pay are skipped before dataset billing.

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

Hard cap on saved remote job records across all searches. Default 100; use a low value such as 20 for a quick test.

## `maxItemsPerSearch` (type: `integer`):

Compatibility alias used when Max jobs is not set. Limits records across the run when only one search is supplied.

## `maxPagesPerSearch` (type: `integer`):

Maximum Indeed result pages to load per search. Each page contains about 15 cards; the default 5 pages bounds proxy use.

## `includeFullDescription` (type: `boolean`):

Visit each matching job detail page and best-effort add plain-text and HTML descriptions. A challenged detail page leaves the job record intact with null description fields; this costs more proxy bandwidth and is off by default.

## `parseCompanyDetails` (type: `boolean`):

Best-effort backfill missing company profile URLs from detail pages. A challenged detail page leaves the existing record unchanged and this also enables the detail-page request path for the run.

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

**Residential Apify Proxy is required for reliable Indeed access.** Keep the default RESIDENTIAL group unless you have an approved proxy setup.

## `dryRun` (type: `boolean`):

Parse and filter matching jobs without writing dataset records. Logs show the accepted count; use this to check a search before a billed run.

## Actor input object example

```json
{
  "searches": [
    {
      "query": "software engineer",
      "location": "Remote",
      "country": "us",
      "postedWithinDays": 3
    }
  ],
  "startUrls": [],
  "country": "us",
  "postedWithinDays": 3,
  "sort": "date",
  "includeHybrid": false,
  "requireSalary": false,
  "maxItems": 100,
  "maxPagesPerSearch": 5,
  "includeFullDescription": false,
  "parseCompanyDetails": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  },
  "dryRun": false
}
```

# Actor output Schema

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

Flat list of accepted remote Indeed job records — one record per unique job. Fields include title, company, structured salary, location, remote work type, posted date, snippet, apply URL, and optional full 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 = {
    "searches": [
        {
            "query": "software engineer",
            "location": "Remote",
            "country": "us",
            "postedWithinDays": 3
        }
    ],
    "startUrls": [],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("schnellscrapers/indeed-remote-jobs").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 = {
    "searches": [{
            "query": "software engineer",
            "location": "Remote",
            "country": "us",
            "postedWithinDays": 3,
        }],
    "startUrls": [],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("schnellscrapers/indeed-remote-jobs").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 '{
  "searches": [
    {
      "query": "software engineer",
      "location": "Remote",
      "country": "us",
      "postedWithinDays": 3
    }
  ],
  "startUrls": [],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call schnellscrapers/indeed-remote-jobs --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,schnellscrapers/indeed-remote-jobs"
        }
    }
}

```

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/R9AZvdYHGkSjpUqho/builds/Lswrm0P0bTTgap9Bc/openapi.json
