# Remote Jobs Scraper — Remote OK Listings, Salary Filter, Links (`hermeskd/remote-jobs`) Actor

Get current remote jobs from Remote OK filtered by keyword, tag, seniority, country and stated USD salary, each with its original listing link and attribution, emails and phones redacted. From $0.001 a job, a dollar per thousand. Callable by AI agents.

- **URL**: https://apify.com/hermeskd/remote-jobs.md
- **Developed by:** [Logan Parker](https://apify.com/hermeskd) (community)
- **Categories:** Jobs, Automation, Agents
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.80 / 1,000 job returneds

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

Get current remote jobs from Remote OK filtered by keyword, tag, seniority, country and stated salary — each with its title, company, location restrictions, annual USD salary when the listing states one, date, tags and the original listing link, credited "via Remote OK". For job seekers' tools and AI agents that must cite where a job came from: keep the link and the credit, and do not resubmit these jobs to other job sites. From $0.001 a job, a dollar per thousand jobs.

### Example result

A job record from the production image's run of the smoke input against the live source (2026-10-26T12:48:26Z). The run's first record is a free summary of listings read, matching and returned.

```json
{
  "type": "job",
  "source": "remoteok",
  "attribution": "via Remote OK",
  "jobId": "1137571",
  "title": "Senior Software Engineer",
  "company": "Klardaten",
  "seniority": [
    "Senior"
  ],
  "categories": [
    "dev",
    "senior",
    "javascript",
    "typescript",
    "full stack",
    "api"
  ],
  "locationRestrictions": [],
  "location": {
    "raw": null,
    "city": null,
    "region": null,
    "country": null,
    "remote": true
  },
  "salary": {
    "min": 80000,
    "max": 100000,
    "currency": "USD",
    "period": "year",
    "source": "stated"
  },
  "postedAt": "2026-10-25T12:34:21Z",
  "descriptionMarkdown": null,
  "applyUrl": "https://remoteOK.com/remote-jobs/remote-senior-software-engineer-klardaten-1137571",
  "sourceUrl": "https://remoteOK.com/remote-jobs/remote-senior-software-engineer-klardaten-1137571",
  "ok": true,
  "matchedTerms": [
    "engineer"
  ]
}
```

### How to use it

Start a run in Apify Console, by API or from an agent with an input like this one — it is the input Apify runs every day to test this Actor:

```json
{
  "keywords": [
    "engineer"
  ],
  "maxResults": 10
}
```

| Field | Type | Meaning |
|---|---|---|
| `keywords` | array | Return only listings whose title, company or tags contain any of these words or phrases (case-insensitive). |
| `categories` | array | Return only listings carrying any of these Remote OK tags (dev, design, marketing, sales, …). |
| `seniority` | array | Return only listings whose tags or title name any of these levels (intern, junior, senior, lead, principal, staff). |
| `countries` | array | Accept listings open worldwide or restricted to any of these countries (names or ISO 3166-1 codes). |
| `salaryMin` | integer | Return only listings whose stated annual USD range reaches this amount; listings stating no salary are left out. |
| `postedWithinDays` | integer | Return only listings posted in the last N days; 1–365, default 14. |
| `sources` | array | Sources to read: remoteok (the only permitted source; Himalayas is excluded under its terms). |
| `maxResults` | integer | Most listings returned, newest first; 1–1,000. |
| `includeDescription` | boolean | Return each listing's description as redacted Markdown. |

### Events and prices

| Event | Title | Charged when | FREE / BRONZE | SILVER | GOLD / PLATINUM / DIAMOND |
|---|---|---|---|---|---|
| `job-returned` | Job returned | One posting returned. | $0.001 | $0.0009 | $0.0008 |

Worked cost: a search returning 50 listings costs 50 × $0.001 = $0.05 at the FREE and BRONZE price, $0.045 on SILVER and $0.04 on GOLD and above, plus the actor-start event.

Platform usage is not passed through. Apify's automatic actor-start event remains $0.00005 per started GB (one GB or less counts once). The synthetic dataset-item event is absent. Failure records and the free summary records are never charged; when the run's maximum total charge is reached, further work stops and the rest gets uncharged `charge_limit_reached` records. Work completed before an abort is settled.

### Call it from an agent

Through Apify's MCP server (https://mcp.apify.com) use `call-actor`:

```json
{
  "actor": "hermeskd/remote-jobs",
  "input": {
    "keywords": [
      "engineer"
    ],
    "maxResults": 10
  },
  "callOptions": {
    "maxTotalChargeUsd": 0.05,
    "timeout": 600
  },
  "waitSecs": 30
}
```

Then call `get-dataset-items` with the returned defaultDatasetId. Dedicated tool URL: https://mcp.apify.com?tools=hermeskd/remote-jobs

### Output fields

| Field | Meaning |
|---|---|
| `type` | summary: the run's first record, free (jobs read, matching and returned, failed sources); job: one listing. |
| `sources` | Summary record: the sources read (Remote OK; Himalayas is excluded under its terms). |
| `source` | The listing's source: remoteok. |
| `attribution` | Credit to show with the job, e.g. "via Remote OK": the source asks to be named. |
| `jobId` | Remote OK listing id. |
| `title` | Job title. |
| `company` | Hiring company as the listing names it. |
| `seniority` | Seniority only where the listing's own tags name one (Intern, Junior, Senior, Lead, Principal, Staff). |
| `categories` | The listing's own tags. |
| `locationRestrictions` | Where the listing says applicants must be; empty when it states no restriction. |
| `location` | Location parsed from the source text: raw text, and city, region (US state code) and ISO 3166-1 alpha-2 country only when the text states them unambiguously; remote when the source says so. |
| `salary` | Pay range only when the source states one; never inferred. |
| `postedAt` | When the listing was posted (UTC, ISO 8601). |
| `descriptionMarkdown` | Description as Markdown with emails and phone numbers redacted; null unless includeDescription is true. |
| `applyUrl` | The listing's apply link as the source gives it. |
| `sourceUrl` | The original listing URL, unmodified: link to it (a followed link) wherever the job is shown. |
| `matchedTerms` | The keywords this listing matched. |
| `sourceJobs` | Summary record: listings read per source. |
| `matchingJobs` | Summary record: listings matching the filters. |
| `returnedJobs` | Summary record: listings returned (maxResults applied). |
| `failedSources` | Summary record: sources that could not be read this run. |
| `ok` | True for a summary of a successful read and for every returned listing. |
| `error` | Failure, never charged. |

### Limits and run time

One request per run: the Remote OK feed, which carries its latest listings (99 on 2026-10-26). 1–1,000 results (`maxResults`, default 100), newest first; `postedWithinDays` defaults to 14. Remote OK states salary as an annual USD range (its listing pages show it as "$min — $max/year"), so `salaryMin` compares USD a year and leaves out listings that state none. Seniority is only what the listing's own tags or title name; a location restriction is matched to a country only when it names one (a city alone matches no country). The smoke input (ten results) ran in 3.4 seconds end to end in the production image on 2026-10-26; the default run timeout is 600 seconds. Cold platform time, cost and the smallest passing memory are measured by the deploy.

### Errors

| Code | Meaning |
|---|---|
| `source_unavailable` | The Remote OK feed could not be read this run; the summary record says so, nothing is charged. |
| `rate_limited` | The source asked us to slow down (HTTP 429); nothing was charged. |
| `source_schema_changed` | The source's response no longer has the verified shape; the run fails loudly when every input does. |
| `download_failed` | The request failed, timed out or answered an unexpected HTTP status. |
| `robots_disallowed` | robots.txt forbids fetching the URL; no request was made to it. |
| `blocked_host` | The host is on the deny-list or resolves to a private or local address; no request was made. |
| `timeout` | The input did not finish within the run's time budget. |
| `invalid_input` | The run input passed the input schema but cannot be used; the message names the field. |
| `internal_error` | Unexpected failure; the message carries the error class. |
| `charge_limit_reached` | The run reached its maximum total charge; this input was not processed. |

No failure record is charged. A run fails only when every input failed on the Actor's side (`internal_error`, `timeout`, `source_schema_changed`); caller-side failures and mixtures leave the run SUCCEEDED.

### Sources and terms

Remote OK (`remoteok.com/api`). Its terms are the `legal` notice at the head of the feed, read 2026-10-26: "Please link back (with follow, and without nofollow!) to the URL on Remote OK and mention Remote OK as a source", and do not use the Remote OK logo without written permission. Every record carries `sourceUrl` and `attribution`; no logo field is returned. Himalayas is not a source: its terms (current as of 2026-10-25) say its jobs may be shown "only on sites and apps you operate" and not passed "to other job boards, aggregators"; Remotive is excluded for the same reason. Only process content you have the right to process. Every request obeys HermesBot robots-group selection, the shared deny-list, public-address checks on connections and redirects, an honest user-agent, a 30-second deadline per request and at most one request a second per host (Lever and Remote OK ask `Crawl-delay: 1`). No caller credentials, cookies, CAPTCHA solving, residential proxies or evasion. Job text is returned with email addresses and phone numbers redacted; no recruiter, applicant or hiring-team object is ever read or returned, and the application endpoints are never called.

### Not affiliated

This Actor is not affiliated with Remote OK, Apify or the companies whose listings it returns. Third-party names describe the source.

### Related Hermes Actors

- [Greenhouse Job Board Scraper — Open Jobs, Live, Any Company](https://apify.com/hermeskd/greenhouse-jobs) — every open job on a company's Greenhouse board.
- [Lever Jobs Scraper — Postings from Any Lever Site, US & EU](https://apify.com/hermeskd/lever-jobs) — every published job on a company's Lever site, global or EU.
- [Career Site Job Search — Verified Greenhouse & Lever Boards](https://apify.com/hermeskd/ats-job-search) — search open jobs in the Hermes directory of Greenhouse and Lever boards, each confirmed live.
- [Company ATS Finder — Which Hiring System & Job Board It Uses](https://apify.com/hermeskd/company-ats-board) — which hiring system and job board a company uses.
- [URL to Markdown for LLMs — From $0.001 a Page, Agent-Payable](https://apify.com/hermeskd/url-to-markdown) — a public job page as clean Markdown where the site allows it (deny-listed job sites are refused).
- [Speech to Text — Transcribe & Translate to English, SRT/VTT](https://apify.com/hermeskd/audio-to-transcript) — speech to text with SRT and VTT subtitles.
- [Video Converter & MP4 to MP3 — Trim, GIF; Audio $0.001 a Minute](https://apify.com/hermeskd/audio-video-convert) — audio and video conversion: MP4 to MP3, trim, GIF.
- [Broken Link Checker That Never Charges for the Broken Links](https://apify.com/hermeskd/broken-links) — broken links, 404s and redirects on a site.
- [DNS Lookup & SPF, DKIM, DMARC Check — Findings by Severity](https://apify.com/hermeskd/dns-and-email-auth) — DNS records and SPF, DKIM and DMARC checks.
- [Word, Excel & PowerPoint to Markdown — $0.002 per Document](https://apify.com/hermeskd/document-to-markdown) — Word, Excel, PowerPoint and other office files to Markdown.
- [Domain Availability Checker — Registry RDAP, No Contact Data](https://apify.com/hermeskd/domain-availability) — whether domain names are available, from registry RDAP.
- [Image to Text OCR — Lines & Words with Boxes, $0.002 an Image](https://apify.com/hermeskd/image-to-text) — OCR: the text in images.
- [Image Upscaler — AI Upscale Graphics, Screenshots & Text 2x/4x](https://apify.com/hermeskd/image-upscale) — AI upscaling of graphics, screenshots and text, 2x or 4x.
- [Lighthouse Audit, No API Key — Lab Core Web Vitals & SEO Scores](https://apify.com/hermeskd/lighthouse-audit) — Lighthouse scores and Core Web Vitals.
- [PDF to Markdown & Text — $0.0005 a Text Page, OCR for Scans](https://apify.com/hermeskd/pdf-to-markdown) — PDF to Markdown and text, with OCR for scanned pages.
- [SEO Audit — On-Page Checks, Schema & Hreflang, $0.004 a Page](https://apify.com/hermeskd/seo-page-audit) — an on-page SEO audit: meta tags, schema, headings and links.
- [Sitemap URL Extractor — Indexes, Gzip, RSS; $0.0003 per URL](https://apify.com/hermeskd/sitemap-urls) — the URLs in a site's sitemaps.
- [Video Frame Extractor — by Scene, Interval or Timestamp](https://apify.com/hermeskd/video-frames) — frames, thumbnails and scenes from a video.
- [Website Screenshot API — Elements, HTML, Dark Mode & PDF Print](https://apify.com/hermeskd/website-screenshot) — screenshots and PDF prints of web pages.

### Changelog

2026-10-26: first version (build unit 5): Remote OK only (Himalayas excluded under its changed terms), filters, attribution, redaction; listing written to the amended store contract.

# Actor input Schema

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

Return only listings whose title, company or tags contain any of these words or phrases (case-insensitive).

## `categories` (type: `array`):

Return only listings carrying any of these Remote OK tags (dev, design, marketing, sales, …).

## `seniority` (type: `array`):

Return only listings whose tags or title name any of these levels (intern, junior, senior, lead, principal, staff).

## `countries` (type: `array`):

Accept listings open worldwide or restricted to any of these countries (names or ISO 3166-1 codes).

## `salaryMin` (type: `integer`):

Return only listings whose stated annual USD range reaches this amount; listings stating no salary are left out.

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

Return only listings posted in the last N days; 1–365, default 14.

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

Sources to read: remoteok (the only permitted source; Himalayas is excluded under its terms).

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

Most listings returned, newest first; 1–1,000.

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

Return each listing's description as redacted Markdown.

## Actor input object example

```json
{
  "keywords": [
    "engineer"
  ],
  "postedWithinDays": 14,
  "sources": [
    "remoteok"
  ],
  "maxResults": 10,
  "includeDescription": false
}
```

# Actor output Schema

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

No 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 = {
    "keywords": [
        "engineer"
    ],
    "maxResults": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("hermeskd/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 = {
    "keywords": ["engineer"],
    "maxResults": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("hermeskd/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 '{
  "keywords": [
    "engineer"
  ],
  "maxResults": 10
}' |
apify call hermeskd/remote-jobs --silent --output-dataset

```

## MCP server setup

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