# RemoteOK Jobs Scraper \[Only $0.99💰] \[/w EMAILS] (`memo23/remoteok-jobs-scraper`) Actor

Scrape the FULL RemoteOK board — 1,000+ live remote jobs, not the API's newest 100 — with complete descriptions, salary ranges, tags, benefits, and geo eligibility. Opt-in employer contact emails turn jobs into leads. Filter by tag, keyword, country, salary. $0.99/1K. JSON, CSV, Excel

- **URL**: https://apify.com/memo23/remoteok-jobs-scraper.md
- **Developed by:** [Muhamed Didovic](https://apify.com/memo23) (community)
- **Categories:** Jobs, AI, Agents
- **Stats:** 2 total users, 1 monthly users, 50.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.99 / 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

## RemoteOK Jobs Scraper

Scrape the **entire live RemoteOK board** — 1,000+ remote jobs, not just the 100 newest that RemoteOK's public API returns — with full job descriptions, salary ranges, tags, benefits, applicant-location eligibility, and opt-in **employer contact emails**. Built for recruiters, job boards, market researchers, and lead-gen teams who need remote-hiring data that is actually complete.

![How RemoteOK Jobs Scraper works](https://raw.githubusercontent.com/muhamed-didovic/muhamed-didovic.github.io/main/assets/how-it-works-remoteok.png)

### How it works

1. **Paste a RemoteOK URL** (or set filters) — the main board, a salary-filtered board, or direct job URLs.
2. The actor walks RemoteOK's board feed at ~50 jobs per request — **the whole live board costs ~21 requests**, and every row already carries the complete job record.
3. Filters (keyword, tags, countries, salary, time window, job type) run **before** a job counts toward your `maxItems`, so you only pay for rows you keep.
4. Export JSON, CSV, or Excel from the Apify Console, or stream via the Apify API.

> 💰 **$0.99 per 1,000 jobs.** Full-board depth and full descriptions at the market's lowest price tier.

***

### ✨ Why use this scraper?

- **Full board depth, verified.** RemoteOK's public API stops at the 100 newest jobs (~4 days of postings). This actor reaches the complete live board — 1,000+ jobs going back weeks. Most alternative scrapers are thin wrappers around that 100-job API.
- **Full descriptions, not stubs.** RemoteOK truncates job descriptions at ~1,000 characters in its structured data. This actor recovers the complete text from the page itself — 5,000–20,000 characters where the employer wrote that much.
- **Employer contact emails (opt-in).** Flip `enrichEmails` and each row gains `contactEmail` + `contactWebsite`, discovered from the hiring company's own website. Turns a job feed into a lead list.
- **Broken-data proof.** RemoteOK emits invalid JSON for multi-country listings (missing commas between country objects). This actor repairs it on the fly — precisely the rows where location eligibility matters most.
- **Cheap and fast to run.** Default mode needs no per-job page fetches, so a full-board scrape finishes in seconds and consumes a fraction of the compute of detail-crawling scrapers.

***

### What makes this richer than alternatives

| Capability | This actor | Typical RemoteOK scraper |
|---|---|---|
| **Board depth** | ✅ Full live board (1,000+ jobs) | ❌ Newest ~100 (public API cap) |
| **Description** | ✅ Full text from the page | ⚠️ ~1,000-char API stub |
| **Multi-country eligibility** | ✅ Parsed (invalid JSON repaired) | ❌ Often missing or broken |
| **Contact emails** | ✅ Opt-in enrichment | ❌ |
| **Employer website** | ✅ When the listing exposes it | ❌ |
| **Benefits, work hours, industry** | ✅ Included | ⚠️ Rarely |
| **Paid-placement flags** | ✅ `isSticky` / `isHighlighted` / `isVerified` | ❌ |
| **Filter billing** | ✅ Filtered rows are free | ⚠️ Billed after scraping |

***

### Supported inputs

#### Option A — Search by URL 🔗 (recommended)

Paste any remoteok.com URL into **Start URLs**. Auto-classified:

| URL shape | Meaning |
|---|---|
| `https://remoteok.com/` | Full live board |
| `https://remoteok.com/?min_salary=100000` | Board filtered by minimum salary (server-side) |
| `https://remoteok.com/remote-jobs/{slug}` | One specific job (detail page) |

Mix listing and job-detail URLs in the same array.

#### Option B — Configure with Filters 🎛️

Leave Start URLs empty and set any of `tag` (e.g. `python`, `design`), `searchKeyword` (e.g. `senior engineer`), `minSalary`, `countries`, `jobTypes`, `timeFilter`. Tag and keyword are matched client-side over the full board — RemoteOK has no reliable server-side tag or search filter (verified: its tag boards interleave unrelated jobs), so exact client-side matching is the only honest way to filter this site.

***

### 🎯 Use cases

- **Recruiting & sourcing** — pull every live listing for a skill, salary band, or geography; contact hiring companies directly with enriched emails.
- **Job boards & aggregators** — mirror the complete RemoteOK board into your product with one scheduled run per day.
- **Salary benchmarking** — structured `salary.min` / `salary.max` in USD across 1,000+ remote positions.
- **Lead generation** — every job is a company actively spending money on hiring; `contactEmail` + `companyWebsite` make them reachable.
- **Market research** — tag frequency, benefits offered, and geographic-eligibility trends across the remote market.
- **Job alerts** — schedule daily with `timeFilter: "24h"` and get only fresh postings.

***

### Quick start

Minimal input — full board, up to 1,000 jobs:

```json
{
    "startUrls": ["https://remoteok.com/"]
}
```

Python jobs open to US applicants, posted in the last week, with employer emails:

```json
{
    "tag": "python",
    "countries": ["US"],
    "timeFilter": "7d",
    "enrichEmails": true
}
```

***

### Input configuration

| Field | Type | Default | Notes |
|---|---|---|---|
| `startUrls` | array | `[]` | Any remoteok.com URLs; overrides Option B when non-empty |
| `tag` | string | `""` | Matched against each job's tag chips, client-side |
| `searchKeyword` | string | `""` | Matched over title + company + industry + location; every word must match |
| `minSalary` | integer | `0` | USD/year; server-side param + permissive client check |
| `countries` | array | `[]` | Names (`United States`, `Europe`) or ISO-2 (`US`, `DE`); `Anywhere` jobs always pass |
| `tagsFilter` | array | `[]` | Any-of tag match; `tag` merges into this |
| `jobTypes` | array | `[]` | `FULL_TIME`, `CONTRACT`, … |
| `timeFilter` | select | `""` | `24h` / `7d` / `30d` / `90d` |
| `includeDetailPages` | boolean | `false` | Opt-in per-job page fetch; adds `ogImage` — everything else is already in the row |
| `includeDescription` | boolean | `true` | Off = drop all description fields |
| `cleanHtml` | boolean | `false` | On = plain-text description only |
| `enrichEmails` | boolean | `false` | Opt-in employer email discovery; billed per email found |
| `maxItems` | integer | `1000` | Filtered-out rows never count |

***

### Output overview

One dataset row per job, 30+ fields. Highlights:

- **Identity:** `jobId`, `slug`, `url`, `applyUrl`
- **Job:** `title`, `description` (+ `descriptionHtml`, `descriptionText`, `descriptionUrls[]`), `employmentType[]`, `occupationalCategory[]`, `industry`, `workHours`, `jobBenefits[]`, `tags[]`
- **Company:** `companyName`, `companyLogo`, `companyPageUrl`, `companyWebsite`, opt-in `contactEmail` / `contactWebsite` / `emailEnrichment`
- **Geography:** `applicantCountries[]` (who may apply — `["Anywhere"]` or explicit country lists), `location`, `jobLocationType`
- **Compensation:** `salary { currency, min, max, unit }`, `salaryText`
- **Timing:** `postedDate`, `epoch`, `validThrough`, `applyBefore`
- **Board state:** `isSticky`, `isHighlighted`, `isVerified`, `source`, `scrapedFrom`, `scrapedAt`

***

### Output samples

#### Job row (real smoke-test data, description truncated for display)

```json
{
    "type": "job",
    "jobId": "1135606",
    "slug": "remote-senior-demand-generation-manager-testgorilla-1135606",
    "url": "https://remoteok.com/remote-jobs/remote-senior-demand-generation-manager-testgorilla-1135606",
    "title": "Senior Demand Generation Manager",
    "companyName": "TestGorilla",
    "companyLogo": "https://r2.remoteok.com/jobs/….jpg",
    "companyPageUrl": "https://remoteok.com/company/testgorilla",
    "companyWebsite": "https://testgorilla.com",
    "description": "Hi there, I'm Mehak, interim Head of Marketing at TestGorilla. We're excited to share more about the Sr. Demand Generation Manager role… (7,234 chars total)",
    "descriptionUrls": ["https://www.testgorilla.com/careers/"],
    "jobLocationType": "TELECOMMUTE",
    "applicantCountries": ["Anywhere"],
    "employmentType": ["FULL_TIME"],
    "industry": "Startups",
    "jobBenefits": ["distributed_team", "async", "paid_time_off"],
    "workHours": "Flexible",
    "tags": ["sales", "marketing"],
    "salary": { "currency": "USD", "min": 70000, "max": 100000, "unit": "YEAR" },
    "salaryText": null,
    "postedDate": "2026-08-01T09:04:12+00:00",
    "validThrough": "2026-10-30T09:04:12+00:00",
    "applyBefore": "Oct 30th, 2026",
    "applyUrl": "https://remoteok.com/l/1135606",
    "applyType": "remoteok",
    "directApply": false,
    "isSticky": false,
    "isHighlighted": false,
    "isVerified": true,
    "source": "listing",
    "scrapedFrom": "https://remoteok.com/",
    "scrapedAt": "2026-08-04T09:48:11.102Z"
}
```

With `enrichEmails: true`, matching rows additionally carry:

```json
{
    "contactEmail": "hello@testgorilla.com",
    "contactWebsite": "https://testgorilla.com",
    "emailEnrichment": { "website": "…", "emails": ["…"], "source": "…" }
}
```

***

### Key output fields

#### Identifiers

- **`jobId`** — RemoteOK's numeric id (stable, unique).
- **`slug` / `url`** — canonical job-detail URL.

#### Job information

- **`description`** — the FULL posting text. RemoteOK's own structured data truncates at ~1,000 chars; this actor recovers the complete text from the page (often 5,000–20,000 chars).
- **`tags[]`** — RemoteOK's rendered tag chips, lowercased. Note: RemoteOK auto-tags some listings loosely — a minority of rows carry 20+ generic tags. That is the site's own data, reported faithfully.
- **`jobBenefits[]`** — e.g. `distributed_team`, `async`, `401k_matching`, `equity_compensation`.

#### Company

- **`companyPageUrl`** — the RemoteOK company profile (`/company/{slug}`).
- **`companyWebsite`** — the employer's own site, when the listing exposes it (a minority of rows). With `enrichEmails` on, it seeds email discovery directly.

#### Geography (the load-bearing field)

- **`applicantCountries[]`** — who may apply. Either `["Anywhere"]` or an explicit list like `["United Kingdom", "Australia", "New Zealand"]`. RemoteOK's own JSON for multi-country rows is invalid (missing commas) — this actor repairs and parses it, so the field is populated where wrapper scrapers return nothing.

#### Compensation

- **`salary`** — structured `{ currency, min, max, unit }` from the listing (USD/year). Most rows carry a range; `salaryText` preserves the display string when present.

#### Application

- **`applyUrl`** — `https://remoteok.com/l/{jobId}`, RemoteOK's public apply entry point. See FAQ for why the employer's final ATS URL is not directly exposed.
- **`directApply`** — RemoteOK's own flag for whether applications happen on-platform.

***

### ❓ FAQ

**How is this different from RemoteOK's free API?**
The public API returns only the ~100 newest jobs (about 4 days of postings) with truncated descriptions. This actor walks the full live board — 1,000+ jobs — with complete descriptions, benefits, badges, and repaired country data.

**Why is `applyUrl` a remoteok.com link and not the employer's ATS?**
RemoteOK gates the employer's external URL behind a JavaScript bot-check — verified: their API, their HTML, and their `/l/{id}` redirect all point back to remoteok.com. `applyUrl` is the same public apply entry every visitor uses. Where the listing itself exposes employer links, you get them in `companyWebsite` and `descriptionUrls`; `enrichEmails` closes the rest of the gap with a direct contact email.

**Does the `tag` filter miss jobs?**
No — the opposite. RemoteOK's own tag boards are unreliable (they interleave unrelated jobs — verified during development), so this actor scans the complete board and matches tags client-side against each job's real chips. Exact, reproducible, and misses are never billed.

**Why do some rows have odd tags?**
RemoteOK auto-tags listings and is sometimes generous (a non-technical job carrying `developer`). Tags are reported as the site publishes them. For precise role filtering, combine `searchKeyword` (title/company match) with `tagsFilter`.

**How many jobs will I get?**
The live board holds roughly 1,000 jobs spanning ~3 weeks of postings (it grows and shrinks daily). `maxItems` caps the run; filtered-out rows never count toward it.

**When should I enable `includeDetailPages`?**
Almost never — board rows already contain the complete record. Turn it on only if you want `ogImage` (the social-share card per job). It costs ~1 request per job instead of ~21 total.

**Is `enrichEmails` guaranteed to find an email?**
No — it is best-effort discovery from the employer's website (seeded by `companyWebsite` when the listing exposes it, otherwise name-based lookup with a business-precision guard). You are billed per email found, never for misses.

**Can I schedule it?**
Yes — any Apify schedule works. For a daily "new jobs" feed, set `timeFilter: "24h"` and schedule the actor every morning.

***

### Support

- 🐛 **Issues tab** of this actor — the fastest way to reach me, usually answered within hours.
- 💬 Feature requests welcome: more filters, output fields, or integrations ship on demand.

***

### Additional Services

Need something beyond this actor?

- **Custom scrapers** for any job board, directory, or listing site — delivered as private Apify actors.
- **Managed data feeds** — scheduled runs, deduplication, delivery to your warehouse (BigQuery, Postgres, S3, Google Sheets).
- **Email enrichment at scale** across any of my actors.

Open an issue on this actor or message via my [Apify profile](https://apify.com/memo23) to discuss.

***

### Explore More Scrapers

More job-market actors from the same portfolio — same schema philosophy, same support:

- [WeWorkRemotely Jobs Scraper](https://apify.com/memo23/weworkremotely-jobs-scraper) — the other big independent remote board, with emails.
- [Wellfound Jobs Scraper](https://apify.com/memo23/wellfound-jobs-scraper) — startup jobs with funding context.
- [Y Combinator Jobs Scraper](https://apify.com/memo23/y-combinator-scraper) — every YC company hiring.
- [Glassdoor Scraper](https://apify.com/memo23/glassdoor-scraper-ppr) — jobs + salaries + reviews.
- [Naukri Scraper](https://apify.com/memo23/naukri-scraper) — India's largest job market.

Browse the full catalog: [apify.com/memo23](https://apify.com/memo23)

***

### 🤖 For AI Agents & LLM Apps

This actor is agent-friendly out of the box:

- **Structured, stable schema** — every field is always present (null when unavailable, never omitted), so tool-calling code never branches on missing keys.
- **MCP-ready** — callable through Apify's MCP server; the input schema above is the tool contract. A minimal call is `{ "searchKeyword": "python", "maxItems": 20 }`.
- **Token-friendly modes** — set `cleanHtml: true` for plain-text descriptions, or `includeDescription: false` for compact metadata-only rows that fit hundreds of jobs in one context window.
- **Deterministic filters** — all filtering is exact and client-side; the same input yields the same selection logic on every run.
- **Fast and cheap in loops** — a filtered query typically completes in seconds and only bills matching rows, so agents can iterate freely.

***

### ⚠️ Disclaimer

This actor is an independent tool, not affiliated with, endorsed by, or sponsored by Remote OK / remoteok.com. It accesses only publicly available data — the same pages any visitor sees — and does not bypass authentication, paywalls, or access controls. You are responsible for how you use the data: comply with applicable laws (GDPR/CCPA where relevant), respect RemoteOK's terms of service, and attribute RemoteOK as the source where their data guidelines require it. Job data is scraped from a live site and can change or contain employer-supplied errors; verify before making decisions based on it.

### SEO Keywords

remoteok scraper, remote ok jobs scraper, scrape remoteok, remoteok api alternative, remote jobs scraper, remote job listings data, remoteok full board export, remote jobs dataset, remote job leads with emails, remote hiring companies list, remoteok json csv export, remote job market data, digital nomad jobs scraper, remote developer jobs data, remote jobs api

### License

Apache-2.0

# Actor input Schema

## `startUrls` (type: `array`):

Full remoteok.com URLs to crawl. Mix listing and job-detail URLs in the same array.

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

RemoteOK tag matched against each job's rendered tag chips, e.g. `dev`, `python`, `design`, `machine learning`. **Matched client-side over the full board** — verified: RemoteOK has no working server-side tag filter (tag boards interleave unrelated jobs), so the actor scans everything and keeps only real chip matches. Merged with the Tags filter below. Ignored if Start URLs is non-empty.

## `searchKeyword` (type: `string`):

Keyword filter matched **client-side** over title + company + industry + location (RemoteOK's own `?search=` barely filters server-side, so the actor scans the full board and matches exactly). Every word must match, e.g. `senior engineer` keeps only jobs matching both. For skill tags (`python`, `react`), use the **Tags filter** instead — RemoteOK auto-tags some listings with 40+ generic tags, so tag matching is a separate, deliberate filter. Non-matching rows are never counted toward Maximum items.

## `minSalary` (type: `integer`):

Drives RemoteOK's server-side `?min_salary=N` filter AND a client-side check on the parsed salary range. **Permissive**: jobs without a listed salary are NOT dropped. Leave 0 for no filter.

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

Post-filter on `applicantCountries[]` — keeps jobs open to workers from at least ONE of the listed countries. RemoteOK stores full names (`United States`, `Europe`, `Latin America`); common ISO-2 codes (`US`, `GB`, `DE`, …) are accepted too. Jobs marked `Anywhere`/`Worldwide` always pass. Leave empty for no filter.

## `tagsFilter` (type: `array`):

Post-filter on the job's `tags[]` — keeps jobs carrying ANY of these tags (case-insensitive substring, e.g. `python`, `senior`, `crypto`). The Tag field above merges into this list. Leave empty for no filter.

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

Post-filter on `employmentType[]`. Common values: `FULL_TIME`, `PART_TIME`, `CONTRACT`, `INTERNSHIP` (spelling like `Full-Time` works too). Empty = no filter.

## `timeFilter` (type: `string`):

Post-filter on `postedDate`. Returns only jobs posted within the selected window.

## `includeDetailPages` (type: `boolean`):

**OFF (default)** — emit complete rows straight from the board listing. Fast and cheap: the whole ~1,000-job board costs ~21 requests. All fields are populated except `ogImage`.

**ON** — additionally fetch every job's detail page (~1 request per job). Same schema plus `ogImage`; row content is otherwise identical, so leave this off unless you need it.

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

When **off**, the actor drops `description`, `descriptionHtml`, and `descriptionText` from every row. Useful when you only need the metadata + apply URL and want a smaller dataset.

## `cleanHtml` (type: `boolean`):

When **on**, only the plain-text `description` is emitted (taken from our normalised `descriptionText`); the HTML variants (`description` with markup, `descriptionHtml`) are stripped. Ignored when `includeDescription` is off.

## `enrichEmails` (type: `boolean`):

If enabled, tries to find a contact email for each employer by discovering the company's website (Clearbit) and reading its contact/about pages. Adds contactEmail + contactWebsite columns plus a detailed emailEnrichment object. Best-effort, billed per contact email found; only charged when an email is returned, never for misses.

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

Hard cap on the number of jobs collected. The live RemoteOK board holds ~1,000 jobs; filtered-out rows never count toward this cap. Use it to control billing.

## `maxConcurrency` (type: `integer`):

Maximum number of parallel HTTP tasks (detail pages and email-enrichment lookups).

## `minConcurrency` (type: `integer`):

Minimum number of parallel HTTP tasks.

## `maxRequestRetries` (type: `integer`):

Number of retries before a failed request is given up.

## `proxy` (type: `object`):

Leave empty — the actor already routes all traffic through its own built-in residential proxy at no extra cost to you. Only set this if you want to use your own proxies.

## Actor input object example

```json
{
  "startUrls": [
    "https://remoteok.com/"
  ],
  "tag": "",
  "searchKeyword": "",
  "minSalary": 0,
  "countries": [],
  "tagsFilter": [],
  "jobTypes": [],
  "timeFilter": "",
  "includeDetailPages": false,
  "includeDescription": true,
  "cleanHtml": false,
  "enrichEmails": false,
  "maxItems": 1000,
  "maxConcurrency": 10,
  "minConcurrency": 1,
  "maxRequestRetries": 5
}
```

# 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 = {
    "startUrls": [
        "https://remoteok.com/"
    ],
    "countries": [],
    "tagsFilter": [],
    "jobTypes": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("memo23/remoteok-jobs-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 = {
    "startUrls": ["https://remoteok.com/"],
    "countries": [],
    "tagsFilter": [],
    "jobTypes": [],
}

# Run the Actor and wait for it to finish
run = client.actor("memo23/remoteok-jobs-scraper").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 '{
  "startUrls": [
    "https://remoteok.com/"
  ],
  "countries": [],
  "tagsFilter": [],
  "jobTypes": []
}' |
apify call memo23/remoteok-jobs-scraper --silent --output-dataset

```

## MCP server setup

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

```

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/eDd1xVjZGv7YLqXWM/builds/N42dSSQaENS27aCU5/openapi.json
