# Remote Jobs Aggregator (`khadinakbar/remote-jobs-aggregator`) Actor

Aggregate public remote jobs from RemoteOK, Remotive, Himalayas, Jobicy, Arbeitnow, Working Nomads, and We Work Remotely. Use for recruiters sourcing remote roles. For LinkedIn or Indeed, use sibling scrapers. Returns title, company, salary, applyUrl, source. $0.005/job.

- **URL**: https://apify.com/khadinakbar/remote-jobs-aggregator.md
- **Developed by:** [Khadin Akbar](https://apify.com/khadinakbar) (community)
- **Categories:** Jobs, Lead generation, MCP servers
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 remote jobs

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#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

## Remote Jobs Aggregator

Collect **public remote job listings** from seven specialty boards into one deduplicated dataset. Each row is one unique job with title, company, location, salary when the board publishes it, apply URL, source, and collection time. HTTP-only against public JSON and RSS feeds — no login, no API key, no browser.

Use this Actor when you want a remote-first feed from RemoteOK, Remotive, Himalayas, Jobicy, Arbeitnow, Working Nomads, and We Work Remotely. For LinkedIn salary-and-skills jobs, start with [LinkedIn Jobs Scraper](https://apify.com/khadinakbar/linkedin-jobs-scraper). For Indeed detail pages, continue with [Indeed Job Scraper](https://apify.com/khadinakbar/indeed-job-scraper). For Google Jobs listings, pair it with [Google Jobs Scraper](https://apify.com/khadinakbar/google-jobs-scraper).

### Best fit for this Actor

- You need a current remote-only hiring feed for recruiting, talent intelligence, or a career-tool pipeline.
- You already know a keyword such as `python` or `customer success` and want matching listings capped to a predictable row count.
- You want source provenance (`source`, `jobUrl`, `collectedAt`) so a downstream agent can cite the board.
- For company career-page ATS scraping, use a dedicated ATS Actor instead of this board aggregator.

### Remote Python hiring scan for a recruiter

A recruiter starts with `searchQuery: "python"`, `maxItems: 10`, and the default seven boards. The Actor fetches the public feeds, keeps listings whose title, tags, or snippet contain every word, deduplicates the same title and company, and writes up to ten rows. Each row has an apply URL they can open and a `source` they can cite. They schedule the same input daily and compare `postedAt` to yesterday's export.

### Quick start input

```json
{
    "searchQuery": "python",
    "maxItems": 10,
    "includeDescription": false,
    "dedupe": true
}
```

Omit `searchQuery` to take the latest listings from the selected boards. `maxItems` is the cost ceiling: each saved job is one `remote-job` event.

### Input reference

| Field | Type | What it controls |
|---|---|---|
| `searchQuery` | string | Optional keyword. Every word must appear in title, company, tags, location, or snippet. |
| `sources` | array | Boards to query. Default is all seven. An empty array is invalid. |
| `maxItems` | integer | Unique rows to save, 1–500. Default 25. Prefill 10. |
| `postedWithinDays` | integer | Keep jobs posted within N days. `0` disables. |
| `jobTypes` | array | `full-time`, `part-time`, `contract`, `freelance`, `internship`. |
| `locationKeywords` | array | Keep jobs whose location mentions a term. Worldwide/remote always pass. |
| `excludeKeywords` | array | Drop matching jobs before billing. |
| `includeDescription` | boolean | Add longer `descriptionText`. Default off keeps a short snippet. |
| `dedupe` | boolean | Merge the same title+company across boards. Default on. |

### What data you receive

One dataset item is one unique remote job.

```json
{
    "jobId": "remoteok:python-engineer-acme",
    "title": "Senior Python Engineer",
    "companyName": "Acme",
    "location": "Worldwide",
    "employmentType": "full-time",
    "seniority": "senior",
    "salaryMax": 140000,
    "salaryCurrency": "USD",
    "salaryPeriod": "yearly",
    "tags": ["python", "backend"],
    "applyUrl": "https://remoteok.com/remote-jobs/python-engineer-acme",
    "jobUrl": "https://remoteok.com/remote-jobs/python-engineer-acme",
    "source": "remoteok",
    "postedAt": "2026-09-08T14:57:50.000Z",
    "descriptionSnippet": "Build APIs and data pipelines...",
    "collectedAt": "2026-09-10T12:00:00.000Z"
}
```

| Field | Meaning |
|---|---|
| `title` / `companyName` | Listing headline and employer |
| `location` | Remote eligibility text from the board |
| `employmentType` | Normalized type when published |
| `salaryMin` / `salaryMax` / `salaryText` | Numbers or prose when the board supplies them |
| `applyUrl` / `jobUrl` | Application link and board provenance |
| `source` / `alsoFoundOn` | Winning board and other boards that listed the same role |
| `postedAt` / `collectedAt` | Board date and collection time (ISO 8601) |

### Pricing

This Actor uses **Pay per event** plus **Apify platform usage**. Check the live Pricing tab for current event names and amounts. Typical runs charge one start event plus one named job event per saved dataset row. Only saved job rows receive the named job event. Platform compute is billed separately through usage pass-through.

### Copy-paste API example

```bash
curl "https://api.apify.com/v2/acts/khadinakbar~remote-jobs-aggregator/runs?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"searchQuery":"python","maxItems":10}'
```

Then read `{{datasetId}}/items` and the `OUTPUT` key-value record for `outcome` and `itemsPushed`.

### Agent prompt card

> Collect 10 current remote Python jobs from public remote-job boards. Return title, company, location, salary when present, apply URL, and source. For LinkedIn or Indeed jobs, start with the sibling scrapers. Cap spend with maxItems=10. After the run, read OUTPUT.outcome and treat COMPLETE or PARTIAL as a useful feed.

Hosted Apify MCP exposes this Actor as `apify--remote-jobs-aggregator`. Provide a keyword or omit it for the latest feed. Pagination is `maxItems`, not a cursor into a previous run.

### Best results

Start with a short skill or role keyword rather than a job-board URL. Keep `maxItems` small for MCP calls. Leave `includeDescription` off unless you need the longer text. Arbeitnow contributes only rows marked remote. Credit each board when you republish listings, and follow RemoteOK, Jobicy, and Remotive attribution notes on their public API pages.

### Builder's note

I built this as a feed merger, not a second LinkedIn scraper. I found the public JSON and RSS endpoints already return usable title, company, and apply links, so a browser path would add cost without adding fields. My goal was a predictable MCP row with provenance, not a 2,000-row dump on every Try click.

### Responsible use

Use this Actor only on public listings you are authorized to collect under applicable laws and each board's terms of service. Confirm the live listing before outreach. Job posts can expire between collection and apply time. RemoteOK, Remotive, Himalayas, Jobicy, Arbeitnow, Working Nomads, and We Work Remotely are trademarks of their respective owners. This independent Actor is not affiliated with, associated with, or endorsed by those companies.

### Focused standalone workflow

This Actor is designed as a focused standalone workflow: keyword in, unique remote jobs out. Pair it with sibling scrapers only when you also need LinkedIn, Indeed, or Google Jobs coverage.

# Actor input Schema

## `searchQuery` (type: `string`):

Optional keyword filter applied to title, company, tags, location, and snippet. Example: 'python developer'. Every word must match. Leave empty for the latest listings. This is not a LinkedIn Jobs URL.

## `sources` (type: `array`):

Public remote-job boards to query. Default is all seven. Omit the field to use every board. An empty array is invalid. These are specialty remote boards, not LinkedIn or Indeed.

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

Hard cap on unique dataset rows for this run. Default 25 keeps MCP calls cheap. Each saved job is one remote-job event. This is a cost ceiling, not pagination into a previous run.

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

Keep jobs whose posted date is within this many days. 0 (default) disables the filter. Rows without a parseable date are dropped when this filter is on. This is not a board-native freshness SLA.

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

Keep normalized employment types such as full-time or contract. Empty means every type. Jobs without a type are dropped when this filter is set. This is not visa or salary filtering.

## `locationKeywords` (type: `array`):

Keep jobs whose location mentions at least one term, such as Europe, USA, or Germany. Worldwide/remote locations always pass. Leave empty for no geo filter. This is eligibility text from the board, not a work-authorization check.

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

Drop jobs containing any of these terms in title, company, tags, location, or snippet. Example: 'unpaid'. Excluded rows are never billed. This is a client-side filter, not a board search operator.

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

When off (default), each row keeps a 500-character descriptionSnippet for agent token budgets. Turn on to add descriptionText up to 4,000 characters. Boards that omit descriptions still return the other fields.

## `dedupe` (type: `boolean`):

When on (default), the same title+company on several boards becomes one row. The richer copy wins and the others appear in alsoFoundOn. Turn off to emit every board copy separately. Duplicate rows are never billed twice when this is on.

## Actor input object example

```json
{
  "searchQuery": "python",
  "sources": [
    "remoteok",
    "remotive",
    "himalayas",
    "jobicy",
    "arbeitnow",
    "workingnomads",
    "weworkremotely"
  ],
  "maxItems": 10,
  "postedWithinDays": 0,
  "jobTypes": [],
  "locationKeywords": [],
  "excludeKeywords": [],
  "includeDescription": false,
  "dedupe": true
}
```

# Actor output Schema

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

Dataset items containing title, company, location, salary, apply URL, source, and collection time.

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

Compact OUTPUT record with outcome, itemsPushed, chargedEventCounts, and warnings.

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

Detailed RUN\_SUMMARY including per-board outcomes, duplicate counts, and billing counters.

# 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 = {
    "searchQuery": "python",
    "sources": [
        "remoteok",
        "remotive",
        "himalayas",
        "jobicy",
        "arbeitnow",
        "workingnomads",
        "weworkremotely"
    ],
    "maxItems": 10,
    "postedWithinDays": 0,
    "includeDescription": false,
    "dedupe": true
};

// Run the Actor and wait for it to finish
const run = await client.actor("khadinakbar/remote-jobs-aggregator").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 = {
    "searchQuery": "python",
    "sources": [
        "remoteok",
        "remotive",
        "himalayas",
        "jobicy",
        "arbeitnow",
        "workingnomads",
        "weworkremotely",
    ],
    "maxItems": 10,
    "postedWithinDays": 0,
    "includeDescription": False,
    "dedupe": True,
}

# Run the Actor and wait for it to finish
run = client.actor("khadinakbar/remote-jobs-aggregator").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 '{
  "searchQuery": "python",
  "sources": [
    "remoteok",
    "remotive",
    "himalayas",
    "jobicy",
    "arbeitnow",
    "workingnomads",
    "weworkremotely"
  ],
  "maxItems": 10,
  "postedWithinDays": 0,
  "includeDescription": false,
  "dedupe": true
}' |
apify call khadinakbar/remote-jobs-aggregator --silent --output-dataset

```

## MCP server setup

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

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/aLeztUWQhTlb3jbpa/builds/XSIhEXb9xPWd2ZG1e/openapi.json
