Remotive Remote Jobs Scraper
Pricing
Pay per event
Remotive Remote Jobs Scraper
Pull the full Remotive remote-jobs feed in one call and filter it by category, keyword search, company name, or job type. Returns typed rows — title, company, category, tags, job type, location, salary, plain-text description, posted date.
Pricing
Pay per event
Rating
0.0
(0)
Developer
DevilScrapes
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 hours ago
Last modified
Categories
Share
🎯 What this scrapes
Remotive (remotive.com) publishes its entire current remote-jobs feed as a
single public JSON object at https://remotive.com/api/remote-jobs. This
Actor fetches that feed once per run and filters it client-side by
category, search keywords, company name, and/or job type, cleans every HTML
job description down to plain text, and lands one typed dataset row per
matching job — no pagination, no login, no per-job page visits required.
Remotive's own documented category/search/company_name/limit query
parameters are supposed to filter server-side, but a live probe on
2026-09-10 showed they currently don't: eight different parameter
combinations against the live endpoint all returned the identical payload.
This Actor never depends on that working — every filter runs in Python
against the full fetched feed, so your results are correct today and stay
correct if Remotive ever fixes the bug.
🔥 Features
- 🛡️ We rotate browser fingerprints —
curl-cffiimpersonation replays real Chrome / Firefox TLS handshakes, with an explicit identifyingUser-Agenton top, on every request. - 🔁 We retry with exponential backoff on
408 / 429 / 5xx— up to 5 attempts, honouringRetry-Afterwhenever the target sends it. - 🧱 We fail loud, not silent — a broken upstream feed surfaces as a failed run with a clear status message, never a quiet empty dataset. A narrow filter that legitimately matches nothing still succeeds, with a status message naming exactly what was searched.
- 🧊 We keep the dataset clean — Pydantic-validated typed rows, HTML descriptions stripped to plain text, salary/logo/location fields null-normalized instead of guessed. One malformed record in the feed is skipped with a warning, never crashes the run.
- 🔍 We don't trust the server's own filters — category, search, company, and job-type filtering all run client-side against the full feed, so results are correct even on days the upstream filter is a no-op.
- 💰 You pay only for results that land — Pay-Per-Event pricing. No data, no charge.
💡 Use cases
- Recruiter tooling — pull today's remote-friendly openings for a given category or tech stack.
- Job-board aggregators — mirror Remotive's feed into your own listings alongside the rest of the Devil Scrapes job-board fleet.
- SDR / lead-gen — find companies actively hiring for roles that signal budget or growth.
- Market research — track which categories and job types are trending in remote postings over time.
⚙️ How to use it
- Click Try for free at the top of the page.
- Optionally set
categories,search,company_name, orjob_typesto narrow the feed — leave everything blank to pull the whole current feed (capped bymaxItems). - Click Start. Output streams into the run's dataset.
- Export from Storage → Dataset as JSON, CSV, or Excel — or fetch via the API.
Call it from Python
from apify_client import ApifyClientclient = ApifyClient("<YOUR_API_TOKEN>")run = client.actor("DevilScrapes/remotive-remote-jobs-scraper").call(run_input={"categories": ["Information Technology", "Customer Service"],"search": [],"company_name": "","job_types": [],"maxItems": 100,"proxyConfiguration": {"useApifyProxy": False},})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item["title"], item["company_name"])
📥 Input
| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
categories | array | no | [] | Keep jobs whose category matches ANY of these (case-insensitive, name-or-slug — e.g. "Software Development" or "software-development" both work). |
search | array | no | [] | Keep jobs whose title or description contains ANY keyword (case-insensitive substring). |
company_name | string | no | "" | Case-insensitive substring match on company name. |
job_types | array | no | [] | One or more of full_time / part_time / contract / freelance / internship. |
maxItems | integer | no | 100 | Cap on rows emitted, applied after filtering (1-1000). |
proxyConfiguration | object | no | {"useApifyProxy": false} | Standard Apify Proxy config — optional for this public feed. |
Example input
{"categories": ["Information Technology", "Customer Service"],"search": [],"company_name": "","job_types": [],"maxItems": 100,"proxyConfiguration": { "useApifyProxy": false }}
📤 Output
Every row is one dataset item.
| Field | Type | Notes |
|---|---|---|
job_id | string | Remotive job ID, stringified. |
title | string | Job title. |
company_name | string | Hiring company name. |
company_logo | string | null | Logo URL; null when Remotive reports an empty value. |
category | string | Remotive category (human-readable name). |
tags | array | Tags/skills attached to the posting. |
job_type | string | null | Employment type; null when empty/missing. |
candidate_required_location | string | null | Free-text location requirement; null when empty. |
salary | string | null | Free-text salary, unparsed; null when empty. |
description | string | HTML stripped to clean plain text. |
publication_date | string | Naive ISO-8601 timestamp, passed through from the API. |
url | string | Remotive job page URL. |
Example output
{"job_id": "2091045","title": "Tier III Service Desk Engineer","company_name": "Unio Digital","company_logo": "https://remotive.com/job/2091045/logo","category": "Information Technology","tags": ["azure", "cisco", "security", "helpdesk", "MSP", "ticketing"],"job_type": "full_time","candidate_required_location": "Worldwide","salary": null,"description": "Unio Digital is an Arizona-based managed service provider...","publication_date": "2026-09-07T01:10:43","url": "https://remotive.com/remote-jobs/information-technology/tier-iii-service-desk-engineer-2091045"}
💰 Pricing
Pay-Per-Event — you pay only when these events fire:
| Event | USD | What it is |
|---|---|---|
actor-start | $0.20 | One-off warm-up charge per run |
result | $0.0015 | Per dataset item (→ $1.50 / 1 000 results) |
Example: 1,000 results at the rates above ≈ $1.50. No subscription, no minimum, no card to start — Apify gives every new account $5 of free credit.
🚧 Limitations
Remotive's public feed exposes its current live listings only — there's
no historical archive and no working pagination cursor, so this Actor
returns a single snapshot per run. All filtering happens client-side
against that one snapshot; the Actor never depends on the server's own
category/search/company_name parameters actually filtering anything,
since a live probe on 2026-09-10 found they currently don't. Salary is
Remotive's own free-text field (e.g. "$50-$75 /hour", "$20k -$35k") —
we pass it through as a string rather than parsing it into a number.
❓ FAQ
Is this legal?
We only fetch content the source makes publicly available via its own documented feed. Respect Remotive's terms of service before using output commercially.
Why do categories filters accept both a name and a slug?
Remotive's own category taxonomy uses both forms interchangeably
("Software Development" in the feed, "software-development" in the
docs). This Actor normalizes both sides before comparing, so either form
works.
Why is salary null on most rows?
Remotive's feed itself only populates that field on a minority of
postings — we pass through exactly what the source reports, as null
when it's missing, rather than inventing a number.
What happens if my filters match nothing?
The run still succeeds, with zero rows and a status message naming the filters that were applied — a narrow filter combination is a legitimate outcome, not an error.
💬 Your feedback
Spotted a bug, hit a weird edge case, or need a new field? Open an issue on the Actor's Issues tab on Apify Console — we ship fixes weekly and we read every report.