Busabase
Busabase is an open-source (MIT) database and workspace for AI agents — data, docs, skills, and apps in one place. Run it locally, self-host it inside your network, or use Busabase Cloud, and turn age
Aggregate remote job listings from 5 public job boards into one normalized JSON dataset: title, company, salary, region, tags, apply link. $0.001 per job.
DataTypeScript · DockerfileGitHub @josh99smithOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Aggregate remote job listings from RemoteOK, Remotive, Himalayas, Jobicy and We Work Remotely into one deduplicated JSON feed: title, company, salary, tags and apply URL. Five boards in one run, pay per job. Runs on Apify Store: https://apify.com/josh99smith/remote-jobs-aggregator
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
A remote jobs API that collects remote job listings from five public job boards into one normalized, de-duplicated dataset: RemoteOK, Remotive, Himalayas, Jobicy and We Work Remotely. Every listing gets the same fields (title, company, region, salary, tags, description, apply link). It uses only the boards' official public APIs and RSS feeds and is not a scraper of LinkedIn, Indeed or any site that forbids automated access.Read the full README ↗A remote jobs API that collects remote job listings from five public job boards into one normalized, de-duplicated dataset: RemoteOK, Remotive, Himalayas, Jobicy and We Work Remotely. Every listing gets the same fields (title, company, region, salary, tags, description, apply link). It uses only the boards' official public APIs and RSS feeds and is not a scraper of LinkedIn, Indeed or any site that forbids automated access.
descriptionText is ready for embeddings.For each selected board the Actor calls its public JSON API (RemoteOK, Remotive, Himalayas, Jobicy) or parses its RSS feeds (We Work Remotely: main plus ten category feeds). Salaries such as "$170k - $200k" become numbers, location rules such as "Northern America, LATAM, Europe" become a compact remoteRegion, employment types are unified and HTML descriptions get a plain-text version. Listings are filtered by age, keywords and categories, and each title + company pair is kept once across boards.
{
"sources": ["remoteok", "remotive", "himalayas", "jobicy", "weworkremotely"],
"keywords": ["python", "typescript", "product manager"],
"categories": ["programming", "product"],
"maxJobsPerSource": 200,
"postedWithinDays": 14,
"dedupe": true,
"includeDescription": true
}
One HTTP call:
curl -X POST "https://api.apify.com/v2/acts/josh99smith~remote-jobs-aggregator/run-sync-get-dataset-items?token=<YOUR_API_TOKEN>" \
-H "Content-Type: application/json" \
-d '{"keywords": ["python"], "postedWithinDays": 7}'
Python (apify-client):
from apify_client import ApifyClient
client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("josh99smith/remote-jobs-aggregator").call(
run_input={"sources": ["remoteok", "remotive", "jobicy"], "keywords": ["python", "django"], "postedWithinDays": 7}
)
for job in client.dataset(run["defaultDatasetId"]).iterate_items():
print(job["title"], "-", job["company"], job["url"])
JavaScript or TypeScript (apify-client):
import { ApifyClient } from "apify-client";
const client = new ApifyClient({ token: "<YOUR_API_TOKEN>" });
const run = await client.actor("josh99smith/remote-jobs-aggregator").call({
keywords: ["react", "typescript"],
categories: ["programming"],
postedWithinDays: 7,
includeDescription: false,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
The Actor is exposed as a tool by the Apify MCP server, so an AI agent can call it by name. Add this to your MCP client configuration (Claude Desktop, Claude Code, Cursor, VS Code, Windsurf and others):
{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com?tools=josh99smith/remote-jobs-aggregator",
"headers": { "Authorization": "Bearer <YOUR_API_TOKEN>" }
}
}
}
Then ask, for example: "Find remote TypeScript jobs posted in the last 7 days with josh99smith/remote-jobs-aggregator." The agent fills in the input, runs the Actor and reads the dataset back; you pay the same per-result price as in the Console.
The Actor can also be scheduled, or connected to Zapier, Make, n8n and Google Sheets in the Integrations tab.
One record per job (description trimmed):
{
"id": "jobicy:153610",
"source": "Jobicy",
"success": true,
"title": "Manager, Clinical Review and Quality Assurance",
"company": "SmithRx",
"companyLogo": "https://jobicy.com/data/server-nyc0409/galaxy/mercury/2025/07/fa1482ea-221.jpeg",
"location": "USA",
"remoteRegion": "US",
"category": "Healthcare & Medical",
"tags": ["Healthcare & Medical", "Senior"],
"employmentType": "Full-Time",
"salaryMin": 136000,
"salaryMax": 192000,
"salaryCurrency": "USD",
"salaryPeriod": "yearly",
"salaryRaw": "USD 136000 - 192000 yearly",
"descriptionHtml": "<p><strong>Who We Are:</strong></p><p>SmithRx is a rapidly growing, venture-backed Health-Tech company...</p>",
"descriptionText": "Who We Are:\n\nSmithRx is a rapidly growing, venture-backed Health-Tech company...",
"url": "https://jobicy.com/jobs/153610-manager-clinical-review-and-quality-assurance-2",
"applyUrl": "https://jobicy.com/jobs/153610-manager-clinical-review-and-quality-assurance-2",
"publishedAt": "2026-09-18T14:43:04.000Z",
"fetchedAt": "2026-09-18T19:46:35.436Z",
"isNew": true
}
An unreachable board produces a free record instead of stopping the run:
{ "success": false, "source": "Remotive", "errorType": "rate-limited", "error": "HTTP 429 Too Many Requests for https://remotive.com/api/remote-jobs?limit=200", "fetchedAt": "..." }
| Field | Description |
|---|---|
id, source | Board-prefixed id (remoteok:1137400) and board name (RemoteOK, Remotive, Himalayas, Jobicy, We Work Remotely). |
title, company, companyLogo | Title, employer, logo URL. |
location | Board's own location text. |
remoteRegion | Worldwide, US, Canada, LATAM, UK, EU, APAC, Africa or Middle East; comma-separated when several apply, null when unknown. |
category, tags[] | Primary category; board tags, skills or industries. |
employmentType | Full-Time, Part-Time, Contract, Freelance, Internship, Temporary or null. |
salaryMin, salaryMax, salaryCurrency, salaryPeriod, salaryRaw | Parsed range plus original text; null when unpublished. |
descriptionHtml, descriptionText | Full HTML (max 20,000 characters, optional); plain-text excerpt (first 2,000). |
url, applyUrl, publishedAt, fetchedAt | Listing URL, apply link, ISO 8601 timestamps. |
isNew | true unless an earlier run with the same state store delivered the job; always present. |
raw | With Include raw source record only: the untouched board item. |
errorType, error | Failures only: dns, timeout, blocked, http-error, network, , or . |
The SUMMARY key-value record gives per-board counts (fetched, filtered, de-duplicated, billed) plus newItems, alreadySeen and stateStoreName.
With Only new items since the last run on, the Actor stores the id of every delivered job in a named key-value store (remote-jobs-aggregator-seen by default). The first run returns everything matching your filters; later runs return only listings not seen in an earlier run. Skipped jobs are never billed.
For alerts, schedule hourly runs and connect the dataset to Slack, email, Discord, Google Sheets or a webhook in the Integrations tab. The store is shared by all runs in your account, so give each keyword set you track its own State store name (for example python-eu and design-worldwide).
Ids absent for Forget seen items after (days) (default 90) are dropped and count as new if they return; the store holds at most 100,000 ids. With monitor mode off, isNew still marks previously seen jobs.
You pay a flat price per job record (shown next to the Start button; at $0.001 per job, 1,000 jobs cost $1). Start-up, filtering, de-duplication, jobs skipped by monitor mode and boards that fail to load are free, and the Actor stops when a run reaches the maximum cost you set. A default run (five boards, 200 jobs each, last 30 days) yields 500 to 700 unique listings.
How it compares (September 2026). Other multi-board aggregators on Apify Store charge $0.002 per unique job, or $0.015 per job plus $0.01 for salary data; single-board scrapers charge $0.001 for one board. This Actor covers five boards for $0.001 per job, adds monitor mode so scheduled runs only return new listings, and never bills jobs removed by your keyword, category or date filters.
Each board asks for credit in return for its feed. When you display or republish records, honour the requirement of the board in source:
url on Remote OK with a normal (follow) link and name Remote OK as the source. Do not use their logo without permission.url and name Remotive as the source. Do not submit their jobs to other aggregators (Jooble, Google Jobs, LinkedIn Jobs, ...) and do not gate listings behind a sign-up form.url from the feed.Always send applicants to the original posting rather than re-hosting the application.
programming matches "Full-Stack Programming" and "Software Development"; tags count too, so python works as a category.go does not match "Django"; c++ and node.js work.The Actor reads only endpoints the boards publish for this purpose, at low request rates, and stores no personal data. Complying with each board's attribution conditions and applicable law is your responsibility.
Boards expose only their newest listings (RemoteOK about 100, Remotive a small public sample, Jobicy up to 200, Himalayas and We Work Remotely a few hundred), so Max jobs per source tops out at 1,000 per board and postedWithinDays removes older ones.
Each run fetches the boards live; Remotive delays its public feed by about 24 hours.
Delete the store named in State store name (remote-jobs-aggregator-seen unless you changed it) under Storage > Key-value stores in Apify Console; the next run returns everything again. To keep the old watchlist, set a new State store name instead.
No. Those sites prohibit automated access and offer no public feed.
No. Existing fields are never renamed or removed without a major version bump announced in the changelog; new fields are only ever added.
Best Damn Remote Jobs Aggregator plugs into the tools you already use through Apify integrations, so results can flow on without anyone downloading a file. Ready-made connectors include:
You can also attach webhooks to trigger your own endpoint whenever a run succeeds, fails or times out. For example, send matching jobs to Slack or email every hour, or sync them into an Airtable job board.
Missing a board with a public feed, or found a wrong mapping? Open a ticket in the Issues tab. The Actor is open source under the MIT licence. If this Actor saved you time, a review on its Store page helps other people find it.
The full source code is on GitHub: josh99smith/remote-jobs-aggregator. Stars and pull requests are welcome.
not-foundrate-limitedother