Remote OK APIremoteok.com ↗
Access Remote OK job listings via API. Filter by tag, keyword, or offset. Returns role, company, tags, locations, salary, and direct job URLs.
What is the Remote OK API?
The Remote OK API exposes one endpoint — list_jobs — that returns up to 50 remote job postings per page, each carrying 9 structured fields including role title, hiring company, full tag list, eligible locations, posting date, and salary when publicly listed. You can filter results by tag slug, free-text keyword, or page through the full feed using offset-based pagination.
curl -X GET 'https://api.parse.bot/scraper/4c30a978-425a-486b-9542-6d15eae45537/list_jobs?tag=python' \ -H 'X-API-Key: $PARSE_API_KEY'
Typed, relational, agent-ready
A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.
- Fully typed · autocompletes
- Objects link to objects
- Typed errors & pagination
Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:
uv add parse-sdk uv run parse init uv run parse add --marketplace remoteok-com-api
uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.
"""Walkthrough: RemoteOK SDK — browse and filter remote job listings."""
from parse_apis.remoteok_com_api import RemoteOK, InputFormatInvalid
client = RemoteOK()
# Browse the newest remote jobs across all tags.
for job in client.jobs.list(limit=5):
print(job.role, "at", job.company, "|", ", ".join(job.tags))
# Filter by tag and drill into the first match.
job = client.jobs.list(tag="python", limit=1).first()
if job is not None:
print(job.role, job.url)
if not job.salary_hidden and job.salary is not None:
print("Salary:", job.salary, job.salary_currency)
# Keyword search across roles, companies and tags.
try:
for job in client.jobs.list(search="data engineer", limit=3):
print(job.role, "—", job.company, "posted", job.date_posted)
except InputFormatInvalid as e:
print("Bad filter input:", e.message)
print("exercised: jobs.list (unfiltered / tag / search)")
Returns one page of remote job listings, newest first, one record per job posting. Each record carries the role title, hiring company, the full tag list, remote-eligible locations, the posting date, a stable job id and its Remote OK page URL. Salary is returned only when the site displays it publicly: `salary` is the display string (e.g. '$50k - $70k') with numeric `salary_min`/`salary_max`/`salary_currency`; when the site hides pay behind its Premium tier, `salary_hidden` is true and the salary fields are null. Pages hold up to 50 jobs; pass `next_offset` back as `offset` to continue, and `has_more` is false (with `next_offset` null) on the last page. An offset past the end returns an empty `jobs` array as a valid result. `tag` and `search` may be combined; a tag or keyword with no matches returns an empty page. One round trip per call.
| Param | Type | Description |
|---|---|---|
| tag | string | Remote OK tag slug to filter by, lower-cased before sending (one shape: python). Matches the site's tag pages such as /remote-<tag>-jobs. Omitted = all jobs. |
| offset | integer | Number of jobs to skip; pass the previous response's next_offset to fetch the following page of up to 50 jobs. |
| search | string | Free-text keyword matched by the site's own search against role, company and tags. Omitted = no keyword filter. |
{
"type": "object",
"fields": {
"tag": "tag filter applied (lower-cased) or null",
"jobs": "array of job records: id, slug, url, role, company, tags (full list, lower-case), locations, salary (display string or null), salary_hidden, salary_min, salary_max, salary_currency, date_posted (ISO 8601), verified",
"count": "integer, number of jobs in this page",
"offset": "integer, offset this page started at",
"search": "keyword filter applied or null",
"has_more": "boolean, whether another page exists",
"next_offset": "integer offset for the next page, or null when no more pages"
},
"sample": {
"data": {
"tag": null,
"jobs": [
{
"id": "1137286",
"url": "https://remoteok.com/remote-jobs/remote-data-entry-clerk-astrek-careers-1137286",
"role": "Data Entry Clerk",
"slug": "remote-data-entry-clerk-astrek-careers-1137286",
"tags": [
"non tech",
"data entry",
"admin",
"ops"
],
"salary": "$50k - $70k",
"company": "Astrek Careers",
"verified": true,
"locations": [
"🇺🇸 United States"
],
"salary_max": 70000,
"salary_min": 50000,
"date_posted": "2026-09-02T18:11:17+00:00",
"salary_hidden": false,
"salary_currency": "USD"
},
{
"id": "1137289",
"url": "https://remoteok.com/remote-jobs/remote-driver-st-georges-university-1137289",
"role": "Driver",
"slug": "remote-driver-st-georges-university-1137289",
"tags": [
"sys admin",
"teaching",
"supervisor"
],
"salary": null,
"company": "St. George's University",
"verified": true,
"locations": [
"🇬🇩 Grenada",
"🌏 Worldwide"
],
"salary_max": null,
"salary_min": null,
"date_posted": "2026-09-02T20:01:08+00:00",
"salary_hidden": true,
"salary_currency": null
}
],
"count": 50,
"offset": 0,
"search": null,
"has_more": true,
"next_offset": 50
},
"status": "success"
}
}About the Remote OK API
What the API Returns
The list_jobs endpoint returns a paginated feed of remote job postings from Remote OK, sorted newest first. Each job record includes a stable id, a slug, a direct url to the job page, the role title, company name, a tags array (all lower-cased), a locations array for remote-eligible regions, a salary display string (or null when not publicly disclosed), and the posting date. The response envelope also carries count, offset, has_more, and next_offset for pagination control.
Filtering and Pagination
Three optional inputs shape what list_jobs returns. The tag parameter accepts a Remote OK tag slug (e.g. python, react, devops) and restricts results to postings carrying that tag — the value is lower-cased before the filter is applied. The search parameter performs a free-text match against role, company, and tags. Omitting both returns the full unfiltered feed. To paginate, pass the next_offset from the current response as the offset input on your next call; when has_more is false, next_offset is null and the feed is exhausted.
Salary Coverage
Salary data appears as a human-readable display string in the salary field only when the job poster has made it public on the Remote OK listing. A null value means no salary was disclosed — not that the role is unpaid. This is a data characteristic of the source, not a gap in the API.
Official API Status
Remote OK does publish a basic public JSON feed at remoteok.com/remote-jobs.json, but it offers limited filtering and no pagination controls. This Parse API adds tag filtering, keyword search, offset pagination, and structured per-field responses that the native feed does not expose.
The Remote OK API is a managed, monitored endpoint for remoteok.com — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when remoteok.com changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.
This isn't an official remoteok.com API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.
Will this API break when the source site changes?+
Is this an official API from the source site?+
Can I fix or extend this API myself if I need a new endpoint or field?+
What happens if I call an endpoint that has an issue?+
- Build a job alert bot that polls
list_jobswith atagfilter (e.g.rustorgolang) and posts new listings to Slack or Discord. - Aggregate salary ranges for remote roles by collecting the
salaryfield across tag-filtered pages over time. - Power a niche remote job board by proxying
list_jobsresults filtered to a specific tech stack tag. - Track hiring velocity by recording
countand posting dates per company across repeated API calls. - Generate weekly digests of new remote roles by using
searchto filter by job title keywords likestaff engineerordata scientist. - Enrich a CRM or ATS with remote job metadata (company, tags, locations) by cross-referencing
companyfield values. - Build a job market research dataset by walking paginated pages using
offsetandnext_offsetand storing structured records.
| Tier | Price | Credits/month | Rate limit |
|---|---|---|---|
| Free | $0/mo | 200 | 5 req/min |
| Hobby | $30/mo | 1,000 | 20 req/min |
| Developer | $100/mo | 5,000 | 100 req/min |
| Team | $300/mo | 20,000 | 300 req/min |
| Company | $1,000/mo | 100,000 | 500 req/min |
Each endpoint has a fixed posted price per successful call — most fall between 1 and 10 credits — shown on this API's page before you run it. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.
Does Remote OK have an official developer API?+
tag parameter, free-text search via search, and offset-based pagination via offset and next_offset.How do I retrieve the next page of results?+
list_jobs response includes has_more (boolean) and next_offset (integer or null). When has_more is true, pass next_offset as the offset input on your next call to retrieve the following page of up to 50 jobs. When has_more is false, next_offset is null and there are no further pages.Can I filter jobs by multiple tags at once?+
tag parameter accepts a single tag slug per request. You can issue separate list_jobs calls for each tag and merge results client-side. You can also fork this API on Parse and revise it to add multi-tag filtering as an endpoint parameter.Is application or company detail data available — such as job descriptions, application URLs, or company profiles?+
url, role, company name, tags, locations, and salary. Full job descriptions and application links are not included in the response. You can fork this API on Parse and revise it to add a job-detail endpoint that fetches the full description for a given job id.How fresh are the job listings returned?+
closed or expired field, so monitoring id presence across pages is the reliable way to detect removals.