# Remote OK Job Scraper — Remote Jobs & Salary Data (`b2b_leads/remote-ok-job-scraper`) Actor

Remote OK job scraper for remote work: keyword & tag search, salary, descriptions & apply URLs. Stream to dataset + webhook. Recruiters, job boards, hiring intel, AI & automation.

- **URL**: https://apify.com/b2b\_leads/remote-ok-job-scraper.md
- **Developed by:** [Chidubem Aneke](https://apify.com/b2b_leads) (community)
- **Categories:** Jobs, Developer tools, MCP servers
- **Stats:** 1 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 results

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

## Remote OK Job Scraper

**Collect remote job listings from Remote OK at scale.** Search by keyword and skill tag, filter by company and location, enrich job URLs, and export **clean, structured JSON** streamed to your Apify dataset in real time.

Built for recruiters, job boards, growth teams, data engineers, and AI workflows that need **reliable remote job data** without slow, expensive browser automation.

***

### Why this Actor

| | Remote OK Job Scraper | Typical browser scraper |
|---|----------------------|-------------------------|
| **Speed** | Fast per-job collection | Often several seconds per listing |
| **Memory** | **256 MB** default | 1–2 GB+ |
| **Setup** | Organized input UI — run immediately | Often fragile and high-maintenance |
| **Cost** | Low compute footprint | High |
| **Output** | Structured JSON, LLM-ready | Often messy HTML |
| **Scale** | Large runs — **10,000 items** per run | Often capped lower |
| **Descriptions** | Full job text on every row | Often requires extra steps |

***

### What you get — 20+ fields per job

Every record includes `featureType`, `jobId`, and `scrapedAt` so you can filter, join, and pipe into any workflow.

#### Job search (`featureType: "job"`)

| Field | Description |
|-------|-------------|
| `title` | Job title |
| `company` | Employer name |
| `companyUrl` | Company profile on Remote OK |
| `companyLogo` | Logo URL when available |
| `location` | Listed location or region |
| `tags[]` | Skill and role tags (dev, python, design, etc.) |
| `salary`, `salaryMin`, `salaryMax` | Compensation when listed |
| `employmentType` | Employment type when listed |
| `postedAt` | Original post date |
| `descriptionText` | Full description as plain text |
| `descriptionHtml` | Full description as HTML |
| `applyUrl` | Direct apply link |
| `jobUrl` | Remote OK listing URL |
| `slug` | URL slug for the listing |
| `searchQuery` | Keyword that produced this row |
| `searchTag` | Tag filter that produced this row |
| `position` | Rank within the search batch |

#### Job links (`featureType: "scrape_by_url"`)

Same rich fields as search, plus `sourceUrl` — the exact URL you submitted.

Set `includeRaw: true` to attach extended payload data on any record (larger output, for advanced users).

***

### Features

#### Job search — on by default

Run **multiple keywords and tags in one actor run** — e.g. *software engineer* with tags `dev` and `python`, plus *data scientist* in the same batch. Layer optional filters for title, company, location, and date posted.

Every matching job includes **full description text**, tags, salary when listed, and apply links.

#### Job links

Paste Remote OK job URLs to turn a spreadsheet of links into structured records — ideal when you already have a target list from newsletters, communities, or prior runs.

#### Real-time dataset streaming

Results are **written to your Apify dataset one job at a time** as they are collected. Long runs do not pile up data in memory.

#### Webhook delivery (optional)

Set `webhookUrl` to POST each new job to your CRM, Slack, Zapier, Make, or custom endpoint — in addition to the dataset.

***

### Use cases

- **Remote job boards & newsletters** — fresh listings by role, tag, or keyword
- **Recruiting & talent sourcing** — pipeline dev, design, marketing, and ops roles worldwide
- **Competitive hiring intel** — track which companies post on Remote OK and how often
- **Salary & market research** — compare compensation signals across tags and titles
- **Job alert automation** — webhook into Slack or email when new matches appear
- **URL list enrichment** — start from links and backfill structured job profiles
- **AI & LLM pipelines** — JSON for résumé matching, outreach drafts, and market summaries
- **CRM & warehouse feeds** — Apify API export, webhook push, or direct integrations

***

### LLM & MCP integration

Output is **JSON Lines–friendly structured data** — ideal for ChatGPT, Claude, Gemini, LangChain, LlamaIndex, and custom agents.

#### Recommended workflow

1. Run the Actor with keywords, tags, and filters you care about.
2. Fetch dataset items via [Apify API](https://docs.apify.com/api/v2) or export JSON/CSV.
3. Pass records to your LLM with a system prompt, or index into a vector store.

#### Example: single job for an LLM prompt

```json
{
  "featureType": "job",
  "jobId": "1134396",
  "title": "Senior AI Engineer Architect",
  "company": "Lemon.io",
  "location": "Worldwide",
  "tags": ["dev", "engineer", "senior", "ai", "python"],
  "salary": "$80,000 - $190,000",
  "salaryMin": 80000,
  "salaryMax": 190000,
  "postedAt": "2026-07-02T12:25:12+00:00",
  "descriptionText": "Are you a talented Senior AI Engineer/Architect looking for a remote job...",
  "applyUrl": "https://remoteok.com/l/1134396",
  "jobUrl": "https://remoteok.com/remote-jobs/remote-senior-ai-engineer-architect-lemon-io-1134396",
  "searchQuery": "software engineer",
  "searchTag": "dev"
}
```

#### Apify MCP (Model Context Protocol)

Use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp) so AI assistants can:

- **Run** this Actor with natural-language instructions
- **Read** dataset results directly in the chat
- **Chain** with other Actors (e.g. enrich → score → CRM)

Typical MCP tool flow:

```
User: "Find 25 senior Python remote jobs posted this month on Remote OK"
→ MCP runs Actor with jobKeywords=["senior python"], jobTags=["python","dev"], jobDatePosted=month
→ MCP reads dataset items
→ LLM summarizes top matches and drafts outreach notes
```

#### API quick start

```bash
curl -X POST "https://api.apify.com/v2/acts/YOUR_ACTOR_ID/runs?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "enableJobSearch": true,
    "jobKeywords": ["software engineer"],
    "jobTags": ["dev", "python"],
    "jobDatePosted": "month",
    "jobsPerQuery": 25,
    "maxItems": 500
  }'
```

Dataset items: `GET https://api.apify.com/v2/datasets/{datasetId}/items?format=json`

***

### Input reference

Enable only what you need. All features are independent.

| Input | Type | Default | Description |
|-------|------|---------|-------------|
| **Job search** | | | |
| `enableJobSearch` | boolean | `true` | Keyword and tag search |
| `jobKeywords` | string\[] | `software engineer`, `data scientist` | One search pass per keyword |
| `jobTags` | string\[] | `dev`, `python` | Skill/role tags to narrow results |
| `jobTitle` | string | — | Optional title filter |
| `jobCompany` | string | — | Optional company filter |
| `jobLocation` | string | — | Optional location filter |
| `jobDatePosted` | enum | `month` | `any`, `month`, `week`, `day` |
| `jobsPerQuery` | integer | `25` | Max jobs per keyword/tag combo |
| **Job links** | | | |
| `enableScrapeByUrl` | boolean | `false` | Scrape submitted job URLs |
| `jobUrls` | string\[] | — | Remote OK job page URLs |
| **Output & delivery** | | | |
| `maxItems` | integer | `10000` | Global cap across all modes |
| `webhookUrl` | string | — | Optional real-time POST URL — dataset is always written |
| `webhookFormat` | enum | `json` | `json` (full record) or `slack` (Slack message) |
| `includeRaw` | boolean | `false` | Attach extended payload |
| `proxyConfiguration` | object | residential US | Apify proxy settings |

Full schema: see `.actor/input_schema.json` or the **Input** tab on Apify Console.

***

### Output reference

Each dataset row is one job record. Filter by `featureType`:

| `featureType` | Description |
|---------------|-------------|
| `job` | Job from keyword/tag search |
| `scrape_by_url` | Job from a submitted URL |

**Traceability fields on search results:**

- `searchQuery` — keyword that matched this job
- `searchTag` — tag filter active for this job
- `position` — rank within the search batch

Export formats: **JSON**, **CSV**, **Excel**, **RSS**, or via **API**.

Dataset views on Apify Console:

- **Overview** — title, company, location, tags, salary, links
- **Full details** — descriptions, apply URL, and all metadata

***

### Webhook delivery (optional)

Every record is **always saved to the Apify dataset** first. If you set `webhookUrl` in the **Output & delivery** section, each new job is **also POSTed in real time** to your endpoint.

| Setting | Description |
|---------|-------------|
| `webhookUrl` | Your HTTPS endpoint. Leave empty to use dataset only. |
| `webhookFormat` | `json` — full job object. `slack` — compact Slack incoming-webhook message. |

Webhook delivery is **best-effort**: a failed webhook never stops the run or prevents dataset writes.

**Example — search with Slack alerts**

```json
{
  "enableJobSearch": true,
  "jobKeywords": ["product manager"],
  "jobTags": ["product"],
  "jobDatePosted": "week",
  "jobsPerQuery": 20,
  "webhookUrl": "https://hooks.slack.com/services/YOUR/WEBHOOK/URL",
  "webhookFormat": "slack"
}
```

**Example — search with JSON webhook to CRM**

```json
{
  "enableJobSearch": true,
  "jobKeywords": ["backend engineer"],
  "jobTags": ["dev", "golang"],
  "jobsPerQuery": 50,
  "webhookUrl": "https://your-crm.example.com/api/jobs",
  "webhookFormat": "json"
}
```

***

### Quick start examples

**Default pattern — ready to run on Apify Console**

```json
{
  "enableJobSearch": true,
  "jobKeywords": ["software engineer", "data scientist"],
  "jobTags": ["dev", "python"],
  "jobDatePosted": "month",
  "jobsPerQuery": 25,
  "maxItems": 500
}
```

**Design & creative roles**

```json
{
  "enableJobSearch": true,
  "jobKeywords": ["product designer", "ux designer"],
  "jobTags": ["design"],
  "jobDatePosted": "week",
  "jobsPerQuery": 30
}
```

**Target one company**

```json
{
  "enableJobSearch": true,
  "jobKeywords": ["engineer"],
  "jobTags": ["dev"],
  "jobCompany": "Stripe",
  "jobsPerQuery": 50
}
```

**Enrich a URL list**

```json
{
  "enableJobSearch": false,
  "enableScrapeByUrl": true,
  "jobUrls": [
    "https://remoteok.com/remote-jobs/remote-senior-ai-engineer-architect-lemon-io-1134396"
  ]
}
```

**High-volume multi-tag run**

```json
{
  "enableJobSearch": true,
  "jobKeywords": ["developer"],
  "jobTags": ["dev", "python", "react", "golang", "rust"],
  "jobDatePosted": "month",
  "jobsPerQuery": 100,
  "maxItems": 2000
}
```

***

### Proxy & performance

- **Apify residential proxy (US)** is **enabled by default** — no extra setup required on Apify.
- Default memory: **256 MB** — optimized for efficient long runs.
- Results are **streamed to the dataset** as they are collected; long runs do not pile up data in memory.

***

### Limitations & compliance

- Remote OK listings change frequently; run on a schedule for ongoing coverage.
- Not affiliated with Remote OK. Use responsibly and comply with applicable laws and Remote OK's terms.
- Always respect rate limits and platform policies when collecting job data.

***

### Contact & custom work

Need something beyond this Actor? I build **custom scrapers**, **data pipelines**, and **full-stack web applications** for startups and enterprises.

- **Email:** <dubem115@gmail.com>
- **GitHub:** [github.com/DrunkCodes](https://github.com/DrunkCodes)

Reach out for:

- Custom Apify Actors (any website or data source)
- Remote job, hiring, and market-intelligence projects at scale
- LLM & MCP integrations with your data stack
- Web apps, dashboards, and automation tools

***

*Remote OK Job Scraper · by [DrunkCodes](https://github.com/DrunkCodes)*

# Actor input Schema

## `enableJobSearch` (type: `boolean`):

Search Remote OK jobs by keyword, tag, company, and location. Enabled by default.

## `jobKeywords` (type: `array`):

Main search terms — matched against title, company, description, and tags. One search pass per keyword.

## `jobTags` (type: `array`):

Remote OK skill and role tags (e.g. dev, python, react, design, marketing). Add multiple tags to widen coverage in a single run.

## `jobTitle` (type: `string`):

Optional extra filter on job title (e.g. Senior Engineer).

## `jobCompany` (type: `string`):

Optional employer filter — partial match on company name.

## `jobLocation` (type: `string`):

Optional location filter (e.g. United States, Europe, Worldwide).

## `jobDatePosted` (type: `string`):

Only return jobs posted within this window.

## `jobsPerQuery` (type: `integer`):

Maximum jobs to return per keyword or tag combination (1–1000).

## `enableScrapeByUrl` (type: `boolean`):

Collect structured data from individual Remote OK job page URLs.

## `jobUrls` (type: `array`):

Remote OK job page URLs to collect.

## `includeRaw` (type: `boolean`):

Attach extended record data under the raw field. Larger output — for advanced workflows only.

## `webhookUrl` (type: `string`):

Optional HTTPS endpoint. Each record is always saved to the dataset — the webhook sends an additional real-time POST per job (CRM, Slack, Zapier, Make, custom pipelines).

## `webhookFormat` (type: `string`):

json = full job record. slack = compact Slack incoming-webhook message.

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

Maximum total job records across all enabled modes in this run.

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

Apify proxy configuration. Residential US proxy is recommended for consistent throughput on large runs.

## Actor input object example

```json
{
  "enableJobSearch": true,
  "jobKeywords": [
    "software engineer",
    "data scientist"
  ],
  "jobTags": [
    "dev",
    "python"
  ],
  "jobTitle": "",
  "jobCompany": "",
  "jobLocation": "",
  "jobDatePosted": "month",
  "jobsPerQuery": 25,
  "enableScrapeByUrl": false,
  "jobUrls": [],
  "includeRaw": false,
  "webhookUrl": "",
  "webhookFormat": "json",
  "maxItems": 500,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}
```

# Actor output Schema

## `allResults` (type: `string`):

Complete dataset with every job field from this run.

## `overview` (type: `string`):

Core job fields table view.

## `full` (type: `string`):

All job fields including descriptions.

# 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 = {
    "enableJobSearch": true,
    "jobKeywords": [
        "software engineer",
        "data scientist"
    ],
    "jobTags": [
        "dev",
        "python"
    ],
    "jobTitle": "",
    "jobCompany": "",
    "jobLocation": "",
    "jobDatePosted": "month",
    "jobsPerQuery": 25,
    "enableScrapeByUrl": false,
    "jobUrls": [],
    "includeRaw": false,
    "webhookUrl": "",
    "webhookFormat": "json",
    "maxItems": 500,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "US"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("b2b_leads/remote-ok-job-scraper").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 = {
    "enableJobSearch": True,
    "jobKeywords": [
        "software engineer",
        "data scientist",
    ],
    "jobTags": [
        "dev",
        "python",
    ],
    "jobTitle": "",
    "jobCompany": "",
    "jobLocation": "",
    "jobDatePosted": "month",
    "jobsPerQuery": 25,
    "enableScrapeByUrl": False,
    "jobUrls": [],
    "includeRaw": False,
    "webhookUrl": "",
    "webhookFormat": "json",
    "maxItems": 500,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "US",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("b2b_leads/remote-ok-job-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "enableJobSearch": true,
  "jobKeywords": [
    "software engineer",
    "data scientist"
  ],
  "jobTags": [
    "dev",
    "python"
  ],
  "jobTitle": "",
  "jobCompany": "",
  "jobLocation": "",
  "jobDatePosted": "month",
  "jobsPerQuery": 25,
  "enableScrapeByUrl": false,
  "jobUrls": [],
  "includeRaw": false,
  "webhookUrl": "",
  "webhookFormat": "json",
  "maxItems": 500,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}' |
apify call b2b_leads/remote-ok-job-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=b2b_leads/remote-ok-job-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/jbThn6HYstkfNGw7B/builds/SpKJFT5DBRLW1Ne1b/openapi.json
