# Remote OK Jobs Scraper — official API, one request per run (`entrogix_works/remoteok-jobs`) Actor

Pull remote job listings from Remote OK's public API. One row per job with tags, location, salary when disclosed, and the source URL you are required to link back to. One request per run, filtering done locally. Unofficial; uses the Remote OK public API under its stated terms.

- **URL**: https://apify.com/entrogix\_works/remoteok-jobs.md
- **Developed by:** [Entrogix Works](https://apify.com/entrogix_works) (community)
- **Categories:** Jobs
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.00 / 1,000 job scrapeds

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/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 OK Jobs Scraper — official API, one request per run

Pull the latest remote job listings from **Remote OK's own public API**. One row per job, filtered locally, so **a run is a single HTTP request** no matter how you filter it.

### Before you use the data: the link-back requirement

Remote OK publishes its API with terms attached, returned inside the response itself:

> "Please link back (with follow, and without nofollow!) to the URL on Remote OK and mention Remote OK as a source, so we get traffic back from your site. If you do not we'll have to suspend API access. Please don't use the Remote OK logo without written permission as it's a registered trademark, please DO use our name Remote OK though."

So if you publish or display this data:

- **Link to the `url` field with a followed link** (no `rel="nofollow"`).
- **Credit "Remote OK" as the source.** Every row carries `source: "Remote OK"` so you cannot lose track of where a record came from.
- **Do not use the Remote OK logo.** This Actor returns no logo of any kind, so you will not ship one by accident. Using the name is explicitly allowed.

The terms as returned at run time are saved in the run summary (`apiTermsAtRunTime`), so you always have the version you actually operated under.

### What you get per job

| Field | Example |
|---|---|
| `position`, `company` | `Senior Backend Engineer`, `Acme` |
| `location` | `Orem, UT` |
| `tags` | `["dev", "senior", "digital nomad"]` |
| `salaryMinUsd` / `salaryMaxUsd` | `150000` / `200000` |
| `salaryDisclosed` | `false` for most listings — see below |
| `postedAt`, `ageInDays` | ISO timestamp, `1.4` |
| `url`, `applyUrl` | the Remote OK page and the apply destination |
| `source` | `Remote OK` |

**Salary is published as `0` when it is not disclosed.** Those come back as `null`, never as a zero salary, and `salaryDisclosed` tells you which is which. In testing **1 of 99 listings disclosed pay** — treat any salary analysis from this board as based on a very small slice, and the run summary reports the rate so you can see it.

**Text encoding is repaired.** Remote OK ships some records double-encoded — `St Johnâ€™s` instead of `St John's`, and Arabic place names as mojibake. This Actor detects and fixes that, and leaves anything it cannot confidently repair untouched rather than mangling it further.

### Input

```json
{
  "tag": "dev",
  "term": "",
  "maxItems": 100
}
```

`tag` matches a tag exactly; `term` matches text in the title, company or tags. Both are optional. The API returns the latest 100 listings, and filtering runs on that batch — so narrowing your filter returns fewer rows, not more pages.

You are charged **per job returned**, so a tight filter costs less.

### Summary (key-value store, `SEARCH_SUMMARY`)

`totalJobs`, `availableBeforeFilter`, `uniqueCompanies`, **`salaryDisclosureRate`**, `source`, **`attribution`**, **`apiTermsAtRunTime`**.

### Limits, stated plainly

- The API exposes the latest 100 listings. There is no pagination and no historical archive, so this is a snapshot of what is current.
- Filtering is done on that batch. A rare tag may return only a handful of rows.
- Only job listings are read. Nothing about applicants is collected.

Unofficial; not affiliated with Remote OK. Uses the Remote OK public API under its stated terms.

# Actor input Schema

## `tag` (type: `string`):

Optional exact tag, for example 'dev', 'design', 'marketing', 'customer support'. Leave empty for all tags.

## `term` (type: `string`):

Optional text matched against job title, company and tags. Leave empty to skip.

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

Remote OK returns the latest 100 listings per call, so this caps at 100. You are charged per job returned.

## `minIntervalMs` (type: `integer`):

Pacing safeguard. A normal run makes one request, so this rarely applies.

## `useProxy` (type: `boolean`):

Not needed. The API answers direct requests.

## Actor input object example

```json
{
  "tag": "",
  "term": "",
  "maxItems": 100,
  "minIntervalMs": 3000,
  "useProxy": false
}
```

# Actor output Schema

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

Every job this run produced, as JSON.

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

Counts, salary disclosure rate, and the Remote OK API terms as returned at run time, including the link-back requirement you must follow.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("entrogix_works/remoteok-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 = {}

# Run the Actor and wait for it to finish
run = client.actor("entrogix_works/remoteok-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 '{}' |
apify call entrogix_works/remoteok-jobs --silent --output-dataset

```

## MCP server setup

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