RemoteOK Jobs — clean typed feed with salary
Pricing
$2.00 / 1,000 results
RemoteOK Jobs — clean typed feed with salary
Every RemoteOK posting as clean, typed, deduplicated data — salary parsed into min/max, tags normalized to categories, employment type and location as structured fields, plus the full description. A continuously tailed archive of remoteok.com served at database speed, never rate-limited.
Not just another RemoteOK scraper. Every posting on remoteok.com as clean, typed, deduplicated data — salary parsed into a min/max band, tags normalized to categories, employment type, location and full description as structured fields. A continuously tailed mirror served at database speed, never rate-limited or blocked.
Why this feed, not a live scrape
- Clean, typed, deduplicated. Salary parsed into
salary_min/salary_max, tags normalized intocategories, employment type and location as structured fields, plus the full description — not raw HTML you have to post-process, and no duplicates. - Database speed, and unblockable. You read our continuously maintained mirror, not remoteok.com, so a run answers as a query and can never be rate-limited or blocked.
- Incremental by design. Leave
postedSinceempty and each run returns only the postings that appeared since the last one — the Actor tracks its own cursor, so you poll without re-pulling. - Salary where the board posts it. RemoteOK advertises a compensation band on many roles; it's parsed into typed
salary_min/salary_maxwith currency, ready to filter and sort. - Filter across the whole board in one query.
keyword,salaryMin,remoteOnly, location and description search apply over every posting at once.
Who it's for
- Job-board & SaaS builders — a clean, deduplicated, typed remote-jobs feed to power a site or app — no scraping, parsing or de-duping to maintain yourself.
- Recruiters & talent researchers — the whole RemoteOK board in one query, filterable by keyword, salary and location — structured, not scraped.
- Compensation analysts — the advertised salary band on the roles that post one, parsed into typed min/max with currency — benchmark remote comp by role and tag.
- Labor-market & trend researchers — a clean, deduplicated panel of the remote board — measure what's being hired, in which categories, at what advertised pay.
Quick start
Basic — newest postings
{"maxItems": 10}
Filtered
{"keyword": "engineer","salaryMin": 120000,"remoteOnly": true,"maxItems": 50}
Notification mode — only what appeared since the last run
{"postedSince": ""}
Output
One record per posting:
| field | meaning |
|---|---|
job_id | Stable unique key for the posting, <source>:<id>. Deduplicate across runs and join to your own data on this. |
url | Canonical posting URL. |
title | Job title. |
company | Employer name as the board lists it. |
company_domain | The employer's own web domain, resolved from the posting. |
company_slug | The board's identifier for the employer. |
company_logo_url | Employer logo, when the board provides one. |
location_restriction | Where the posting says the role may be based. |
employment_type | Full time, contract, and so on, as declared by the employer. |
categories | Category tags the board assigned to the posting. |
description | Full posting description. |
salary_min | Lower bound of the advertised band. |
salary_max | Upper bound of the advertised band. |
salary_currency | ISO currency of the advertised band. |
salary_unit | Period the band refers to (e.g. YEAR, HOUR). |
posted_at | When the posting first appeared. |
first_seen_at | When our archive first captured it. |
expires_at | The board's own expiry date, when it exposes one. |
status | live while listed, gone once removed. |
gone_at | The date the posting was first observed gone. Null while it is live. Naukri overwrites its expired list nightly, so this is only knowable to whoever was watching that day. |
apply_url | Where to apply for the role. |
enriched | Whether salary and employment type have been parsed yet — a posting is returned as soon as it is found, enriched or not. |
Example record:
{"job_id": "remoteok_jobs:1135420","url": "https://remoteOK.com/remote-jobs/remote-rsm-ageless-digital-technologies-private-limited-1135420","title": "RSM","company": "Ageless Digital Technologies Private Limited","company_domain": "https://remoteok.com/company/ageless-digital-technologies-private-limited","company_slug": "ageless-digital-technologies-private-limited","company_logo_url": "https://r2.remoteok.com/jobs/a640cd6f3f8026a891204a058f4298c31785038619.jpg","location_restriction": "Mengio, ","employment_type": "FULL_TIME","categories": [],"description": "Name *<br><br>Email *<br><br>Phone *<br><br>Location *<br><br>Current CTC (Yearly) *<br><br>Expected CTC (Yearly) *<br><br>Resume / CV *<br><br>PDF or Word document, up to 5 MB.<br …(truncated for display)","salary_min": 90000.0,"salary_max": 150000.0,"salary_currency": "USD","salary_unit": "YEAR","posted_at": "2026-07-25 21:32:27+00","first_seen_at": "2026-07-26 21:33:28.032339+00","expires_at": "2026-10-23 21:32:27+00","status": "live","gone_at": null,"apply_url": "https://remoteOK.com/remote-jobs/remote-rsm-ageless-digital-technologies-private-limited-1135420","enriched": true}
Pricing
$0.002 per result — pay only for the postings a run returns, with no start fee so you can poll as often as you like. You read a clean, typed, deduplicated mirror of the RemoteOK board — salary parsed, tags normalized, full detail — at database speed, instead of scraping and post-processing remoteok.com yourself.
Usage patterns
- The whole board, typed — Run with no filters (or just a
keyword) and get every current RemoteOK posting as structured records — salary, tags, type, location, description. - Salary-filtered — Set
salaryMinto keep only postings whose advertised band reaches your floor; combine withkeywordandremoteOnly. - Incremental sync — Leave
postedSinceempty; each run continues from the previous one's cursor — no duplicates, nothing skipped.
Input configuration
| field | type | default | what it does |
|---|---|---|---|
keyword | string | Matches job title or category. | |
company | string | Employer name as the board lists it. Partial matches work. | |
postedSince | string | ISO timestamp. Leave empty and the Actor remembers where it stopped, returning only new postings each run. | |
goneSince | string | Only postings observed dead at or after this ISO timestamp. The query this archive exists to answer. | |
status | live / gone / any | "live" | 'Gone' returns postings that have been removed, with why — the part no live scraper can give you. |
location | string | Substring match on the posting's location. | |
remoteOnly | boolean | false | Only postings the employer marks as remote. |
descriptionSearch | string | Substring match inside the job description. | |
excludeTitle | string | Drop postings whose title contains this. | |
maxItems | integer | 500 | Upper bound on results returned in a single run. |
fullRefresh | boolean | false | By default each run returns only what appeared since your last one, so a schedule never re-delivers the same page. Tick this to ignore that bookmark and re-pull the full result set for your filters — and it clears the stored cursor, so your next ordinary run starts clean. |
salaryMin | integer | Matches any posting whose advertised band reaches this figure. A $10-35/hr band matches a request for 35. | |
enrichedOnly | boolean | false | Return only postings whose salary, employment type and description have been parsed. Off by default: an unenriched record still carries title, company, location and dates, and withholding it trades a real answer for a slower better one. |
FAQ
How is this different from other RemoteOK scrapers?
They scrape the board live and hand back raw rows. This is a continuously maintained, deduplicated mirror served at database speed — salary parsed into typed min/max, tags normalized, full detail as clean fields — that can't be rate-limited or blocked, and syncs incrementally so you never re-pull the same job.
Does it track when jobs close (expiry history)?
Not for RemoteOK. RemoteOK postings carry no scheduled expiry and this feed doesn't mark them gone, so treat it as a clean, typed live feed — not an expiry archive. If you need when-and-why-a-role-closed history, that's the Himalayas or WeWorkRemotely archives, whose sources date their postings.
Does it include the employer's real website?
No. RemoteOK's data links back to remoteok.com rather than the employer's own domain, so this Actor doesn't invent one. Every posting carries the company name; for employers resolved to their real website domain, that's the Himalayas archive.
I get no results.
Filters combine with AND. Loosen keyword or salaryMin.
Will I see the same job twice?
Not in notification mode — leave postedSince empty and each run continues where the last one stopped.
Integration
JavaScript
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_TOKEN' });const run = await client.actor('hyperbach/remoteok-jobs-history').call({"maxItems": 10});const { items } = await client.dataset(run.defaultDatasetId).listItems();
Python
from apify_client import ApifyClientclient = ApifyClient('YOUR_TOKEN')run = client.actor('hyperbach/remoteok-jobs-history').call(run_input={'maxItems': 10})items = client.dataset(run['defaultDatasetId']).list_items().items
CLI
$apify call hyperbach/remoteok-jobs-history --input '{"maxItems": 10}'
REST
curl -X POST "https://api.apify.com/v2/acts/hyperbach~remoteok-jobs-history/run-sync-get-dataset-items?token=YOUR_TOKEN" \-H 'Content-Type: application/json' -d '{"maxItems": 10}'
Support
This page is generated from the Actor's schemas and a live sample — it cannot describe a field the Actor does not have.