# Remote Jobs Aggregator: Remote OK, Himalayas, Jobicy & More (`larkmoor/remote-jobs-aggregator`) Actor

Fresh remote jobs from four public job-board APIs (Remote OK, Himalayas, Jobicy, Arbeitnow) in one clean, de-duplicated dataset: title, company, allowed locations, type, seniority, salary, posted date, original job URL and description. Keyword, location, date and salary filters. $2 per 1,000 jobs.

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

## Pricing

from $1.70 / 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 Aggregator: Remote OK, Himalayas, Jobicy & More

Get fresh remote jobs from **four public job-board APIs in one run** — Remote OK, Himalayas, Jobicy and Arbeitnow — normalized into one clean dataset with the same columns for every source: title, company, company logo, allowed locations, employment type, seniority, categories and tags, salary range with currency and period, posted date, the original job URL and the full description as text and HTML. Duplicates (the same company and title on two boards) are removed.

Every source publishes its API for re-use. No browser, no login, no proxies.

### What you can use it for

- **Remote job boards and newsletters**: fill a niche board or a weekly "remote Python jobs" newsletter from four sources with one scheduled run
- **Job alerts**: a daily run with `postedWithinDays: 1` and your keywords sends only new roles to Slack, Telegram, email or a sheet
- **Career search**: one list of every remote "product designer" job that accepts candidates from your country
- **Recruiting and sales leads**: see which companies are hiring remotely, for which roles, right now
- **Salary research**: collect published remote salary ranges by role and seniority
- **Market research**: track the volume of remote roles by category week by week

### Why this one

- **Four sources, one schema**: no more stitching four APIs with four date formats, four salary formats and four location formats
- **$2 per 1,000 jobs**, $0.001 per run start — half of what single-board remote job actors charge
- **Reliable**: official public APIs only, so runs do not fail on bot checks or page redesigns
- **De-duplicated**: the same job posted on two boards appears once
- **Real filters**: keywords (title only or full text and tags), locations ("USA", "Europe", "Worldwide"), posted within N days, salary only — and you only pay for jobs that pass them
- **Attribution kept**: each row names its source and links to the original listing, which is what the sources ask for
- **256 MB memory**, a few hundred jobs in under a minute

### Input

| Field | What it does |
|---|---|
| `sources` | `remoteok`, `himalayas`, `jobicy`, `arbeitnow` (empty = all) |
| `keywords` | Search words; sent to each source's search where it has one and matched in title, tags and description |
| `keywordsInTitleOnly` | Keep only jobs with a keyword in the title |
| `locations` | Keep jobs whose location / allowed countries contain any of these |
| `postedWithinDays` | Only jobs posted in the last N days |
| `withSalaryOnly` | Only jobs with a salary range |
| `dedupe` | Remove the same company + title across sources (default on) |
| `includeDescription` | Include description text and HTML (default on) |
| `maxJobsPerSource` / `maxResults` | Caps per source and for the whole run |

Example:

```json
{
  "keywords": ["python", "django"],
  "locations": ["USA", "United States", "Worldwide"],
  "postedWithinDays": 2,
  "maxJobsPerSource": 100,
  "maxResults": 300
}
```

### Output

```json
{
  "source": "Jobicy",
  "sourceJobId": "155051",
  "title": "Software Engineer, AI Enablement",
  "company": "Tailscale",
  "companyLogo": "https://jobicy.com/data/.../d3fa2e99-221.png",
  "location": "UK",
  "employmentType": "Full-Time",
  "seniority": "Senior",
  "categories": ["Software Engineering"],
  "tags": null,
  "salaryMin": 128770,
  "salaryMax": 178540,
  "salaryCurrency": "GBP",
  "salaryPeriod": "year",
  "postedAt": "2026-10-22T06:40:09+00:00",
  "url": "https://jobicy.com/jobs/155051-software-engineer-ai-enablement",
  "applyUrl": "https://jobicy.com/jobs/155051-software-engineer-ai-enablement",
  "descriptionText": "Thank you for considering Tailscale...",
  "descriptionHtml": "<p>Thank you for considering...</p>"
}
```

### How much does it cost?

**$2.00 per 1,000 jobs** on the Free plan plus **$0.001 per run**, with automatic discounts on paid Apify plans. Platform compute is included. Filters run before you are charged.

Worked examples:

- **Daily alert** for "python" across all four sources, about 25 new jobs a day: **$0.05 a day**, about $1.50 a month
- **Weekly newsletter** with the 300 newest remote jobs: **$0.60 a week**
- **Market snapshot** of 5,000 remote jobs: **$10**

### FAQ

**Is this legal?**
Yes. Each source publishes a free public API for re-use: Remote OK and Jobicy ask that you credit them and link to the original job, Arbeitnow asks for a link back and fair use, Himalayas documents its feed for developers. The actor keeps the source name and original URL on every row so you can follow those terms when you show the jobs. Job ads are public; no login, no candidate data and no personal data are touched.

**How fresh are the jobs?**
As fresh as each source: Remote OK and Jobicy update continuously, Arbeitnow hourly, Himalayas many times a day.

**Why does a location look like a long list of countries?**
Himalayas publishes the exact countries a job accepts candidates from. Filter with `locations` to keep only jobs open to yours.

**Why is the salary empty for some jobs?**
The employer did not publish one. Use `withSalaryOnly` to keep only jobs with a range.

**Can I add another board?**
Tell us in the Issues tab which public job API you want next.

### Tips

- For a job alert, schedule the actor daily with `postedWithinDays: 1`, turn off `includeDescription` to keep rows small, and connect the Slack or email integration.
- Use several close keywords (`["python", "django", "fastapi"]`) instead of one broad word; each is searched separately and duplicates are dropped.
- `locations: ["Worldwide"]` keeps jobs open to anyone; add your country to catch jobs limited to it.
- To compare boards, run once with `dedupe` off and count rows per `source`.

### Integrations

Works with Google Sheets, Slack, Zapier, Make, Airtable, webhooks, the Apify API and the Python and JavaScript clients. Download as JSON, CSV, Excel, XML or HTML.

### Changelog

- **2026-10-22** — First release: Remote OK, Himalayas, Jobicy and Arbeitnow (remote only), one schema, cross-source de-duplication, keyword, location, date and salary filters.

# Actor input Schema

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

Which job boards to read: remoteok, himalayas, jobicy, arbeitnow (Arbeitnow: remote jobs only). Empty = all four.

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

Search words (e.g. 'python', 'designer', 'marketing'). Sent to the source's search where it has one and matched in title, tags and description. Empty = latest jobs.

## `keywordsInTitleOnly` (type: `boolean`):

Only keep jobs whose title contains a keyword (stricter).

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

Keep jobs whose location or allowed-countries text contains any of these (e.g. 'USA', 'United States', 'Europe', 'Worldwide').

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

Keep only jobs posted in the last N days. Empty = any age.

## `withSalaryOnly` (type: `boolean`):

Keep only jobs that publish a salary range.

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

Drop a job when the same company and title already came from another source in this run.

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

Include the job description as plain text and HTML.

## `maxJobsPerSource` (type: `integer`):

Stop after this many kept jobs from one source.

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

Hard cap on rows for the whole run (you pay per job row).

## Actor input object example

```json
{
  "sources": [
    "remoteok",
    "himalayas",
    "jobicy",
    "arbeitnow"
  ],
  "keywords": [
    "python"
  ],
  "keywordsInTitleOnly": false,
  "withSalaryOnly": false,
  "dedupe": true,
  "includeDescription": true,
  "maxJobsPerSource": 200,
  "maxResults": 40
}
```

# Actor output Schema

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

All results as JSON items in the run's default dataset (also downloadable as CSV/Excel from the dataset).

# 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 = {
    "sources": [
        "remoteok",
        "himalayas",
        "jobicy",
        "arbeitnow"
    ],
    "keywords": [
        "python"
    ],
    "maxResults": 40
};

// Run the Actor and wait for it to finish
const run = await client.actor("larkmoor/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 = {
    "sources": [
        "remoteok",
        "himalayas",
        "jobicy",
        "arbeitnow",
    ],
    "keywords": ["python"],
    "maxResults": 40,
}

# Run the Actor and wait for it to finish
run = client.actor("larkmoor/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 '{
  "sources": [
    "remoteok",
    "himalayas",
    "jobicy",
    "arbeitnow"
  ],
  "keywords": [
    "python"
  ],
  "maxResults": 40
}' |
apify call larkmoor/remote-jobs-aggregator --silent --output-dataset

```

## MCP server setup

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