# Remote Jobs Feed - every listing on Himalayas, with source link (`vital_tuxedo/remote-jobs-feed`) Actor

Every remote job Himalayas lists, from the public JSON API it publishes for job boards and AI agents. Browse the whole feed (100k+ jobs, no duplicates) or search by keyword, country, seniority, type, company and timezone. One row per job with salary, categories and source link. No login, no key.

- **URL**: https://apify.com/vital\_tuxedo/remote-jobs-feed.md
- **Developed by:** [Stephen Psaradellis](https://apify.com/vital_tuxedo) (community)
- **Categories:** Jobs, Automation, Agents
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.00 / 1,000 job rows

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/actors/running/actors-in-store.md#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

## Remote Jobs Feed - every listing on Himalayas, with its source link

Every remote job on [Himalayas](https://himalayas.app), read from the public
JSON API Himalayas publishes for exactly this - "to backfill other remote job
boards, power job search experiences, populate internal dashboards, or feed
AI agents and automation workflows". About 100,000 live listings. Browse the
whole feed from newest to oldest with no duplicates, or search by keyword,
country, seniority, employment type, company and timezone. One dataset row
per job: title, company, salary and period, seniority, categories, location
and timezone restrictions, published and expiry dates, the apply link, and
the job's own page on Himalayas.

No login, no API key, no browser. Plain GETs to a documented public endpoint,
and every row carries the attribution its licence asks for.

### Use case

- **Fill a job board or newsletter.** Browse the whole feed once, then run it
  daily with a small `maxRows` - the feed is newest-first, so the first pages
  are today's postings.
- **Watch a niche.** Search `"machine learning"` in `US` at `Senior` and
  compare the rows week to week.
- **Salary research.** About 4 in 10 listings carry a published range, with its
  currency and period, as numbers you can aggregate.
- **Feed an agent.** Ask your assistant over MCP for "remote product design
  roles open to applicants in Europe" and it runs this Actor.

### What you get

| field | what it holds |
|---|---|
| `source`, `source_url` | `Himalayas`, and the job's page on himalayas.app. The API's terms ask that republished rows link back here and name the source - both are on every row, so passing them through is enough. |
| `guid` | the job's stable id (its URL). One row per guid per run, whichever keywords matched it. |
| `title`, `company_name`, `company_slug`, `company_logo` | the role and who is hiring; the slug is what the `company` filter takes |
| `employment_type`, `seniority` | Full Time / Part Time / Contractor / ...; one or more of Entry-level through Executive |
| `min_salary`, `max_salary`, `salary_period`, `currency` | the published range as numbers, or `null` when the employer did not state one |
| `location_restrictions`, `timezone_restrictions` | countries and UTC offsets the employer accepts; empty means anywhere |
| `categories`, `parent_categories` | the venue's fine and coarse role categories |
| `excerpt`, `description_html` | the venue's summary, and the full posting as HTML (`includeDescription`, on by default) |
| `published_at`, `expires_at` | ISO 8601, UTC |
| `apply_url` | where a candidate applies |
| `query` | the keyword that matched, in search mode |
| `read_at` | when the page was read |

The run summary (key-value store, `RUN_SUMMARY`) records the permission
check, pages read, jobs seen, duplicates skipped, rows pushed, per-keyword
counts, and what stopped the run.

### Sample output

Two rows from a browse run on 2026-09-11, descriptions trimmed:

```json
[
  {
    "source": "Himalayas",
    "source_url": "https://himalayas.app/companies/mercor/jobs/business-analyst-fully-remote-upto-160-hr-8973351818",
    "guid": "https://himalayas.app/companies/mercor/jobs/business-analyst-fully-remote-upto-160-hr-8973351818",
    "title": "Business Analyst - Fully Remote | Upto $160/hr",
    "company_name": "mercor",
    "company_slug": "mercor",
    "company_logo": "https://cdn-images.himalayas.app/6jo5q9nua35jgtdfm41nq6b7ocqf",
    "employment_type": "Contractor",
    "seniority": ["Mid-level"],
    "min_salary": 80,
    "max_salary": 160,
    "salary_period": "hourly",
    "currency": "USD",
    "location_restrictions": ["Ireland"],
    "timezone_restrictions": ["1"],
    "categories": ["Business-Analyst", "Document-Review", "Quality-Assurance", "Evaluation-Specialist", "Business-Analysis", "Remote-Business-Analyst"],
    "parent_categories": ["Data Science", "Developer"],
    "excerpt": "About the jobMercor connects elite creative and technical talent with leading AI research labs.",
    "published_at": "2026-09-10T23:36:27.000Z",
    "expires_at": "2026-11-09T23:36:27.000Z",
    "apply_url": "https://himalayas.app/companies/mercor/jobs/business-analyst-fully-remote-upto-160-hr-8973351818",
    "query": "",
    "read_at": "2026-09-11T21:40:46.775Z"
  },
  {
    "source": "Himalayas",
    "source_url": "https://himalayas.app/companies/mercor/jobs/medical-affairs-specialist-fully-remote-upto-200-hr-3694042227",
    "guid": "https://himalayas.app/companies/mercor/jobs/medical-affairs-specialist-fully-remote-upto-200-hr-3694042227",
    "title": "Medical Affairs Specialist - Fully Remote | Upto $200/hr",
    "company_name": "mercor",
    "company_slug": "mercor",
    "company_logo": "https://cdn-images.himalayas.app/6jo5q9nua35jgtdfm41nq6b7ocqf",
    "employment_type": "Contractor",
    "seniority": ["Senior"],
    "min_salary": 200,
    "max_salary": 200,
    "salary_period": "hourly",
    "currency": "USD",
    "location_restrictions": ["India"],
    "timezone_restrictions": ["5.5"],
    "categories": ["Medical-Affairs", "Clinical-Research", "Healthcare-Consulting", "Medical-Writing", "Market-Research", "Remote-Senior-Medical-Affairs-Specialist", "Senior-Medical-Affairs-Specialist"],
    "parent_categories": ["Marketing"],
    "excerpt": "About the jobMercor connects elite creative and technical talent with leading AI research labs.",
    "published_at": "2026-09-11T02:08:33.000Z",
    "expires_at": "2026-11-10T02:08:32.000Z",
    "apply_url": "https://himalayas.app/companies/mercor/jobs/medical-affairs-specialist-fully-remote-upto-200-hr-3694042227",
    "query": "",
    "read_at": "2026-09-11T21:40:42.218Z"
  }
]
```

### How to run it

1. Open the Actor in Apify Console and press **Start**. The defaults browse
   the newest 1,000 jobs in the feed and finish in about twenty seconds.
2. For the whole feed, set **Max jobs** to `0`. That is about 100,000 rows
   and 5,000 requests, read one page at a time with a short pause between,
   and takes roughly half an hour.
3. For a slice, switch **Mode** to *Search*, add keywords one per line, and
   set the filters. The venue returns at most 5,000 jobs per keyword.
4. Read the dataset in Console, export it as JSON or CSV, or fetch it from the
   API with the run's `defaultDatasetId`.

### Sample input

```json
{
  "mode": "search",
  "queries": ["machine learning", "product designer"],
  "country": "US",
  "seniority": ["Senior"],
  "employmentType": ["Full Time"],
  "sort": "recent",
  "includeDescription": false,
  "maxRows": 2000
}
```

### Input

| field | default | notes |
|---|---|---|
| `mode` | `browse` | `browse` reads the feed newest-first with cursor pagination and never repeats a job; `search` asks the search endpoint per keyword |
| `queries` | `[]` | keywords, search mode; a job matched twice is one row |
| `country` | | ISO alpha-2, a country name or a slug |
| `worldwide` | `false` | keep only jobs open to applicants anywhere |
| `seniority` | `[]` | Entry-level, Mid-level, Senior, Manager, Director, Executive |
| `employmentType` | `[]` | Full Time, Part Time, Contractor, Temporary, Intern, Volunteer, Other |
| `company` | | canonical slugs, comma separated |
| `timezone` | | `-5`, `UTC-5`, `UTC+05:30` |
| `sort` | `recent` | recent, relevant, salaryAsc, salaryDesc, nameAToZ, nameZToA |
| `includeDescription` | `true` | keep the full HTML posting on each row |
| `maxRows` | `1000` | stop after this many rows; `0` is unbounded |
| `timeoutSecs` | `20` | per request; retried twice with backoff |

### Pricing

Pay per event, one event:

| event | price | when |
|---|---|---|
| **Job row** | **$0.001** | one job pushed to the dataset |

That is **$1.00 per 1,000 jobs**, and nothing else: no charge for starting
the run, none per page, none for a job the run already pushed. A run that
reads the whole feed - about 100,000 jobs - costs about $100; the default run
costs $1.00. Your account's **Max total charge** on a run is honoured: when it
is reached the Actor stops before the next row rather than after it.

### Use it from code

The **API** tab on this page has ready-made snippets for Node.js, Python and
curl, including `run-sync-get-dataset-items`, which starts a run and returns
the rows in one call. For the whole feed use the asynchronous run and read
the dataset when it finishes.

### Use it from Claude or ChatGPT (Apify MCP)

This Actor is a tool your assistant can call directly, over the
[Model Context Protocol](https://modelcontextprotocol.io). Apify hosts the
server at `https://mcp.apify.com`; adding `?tools=` pins **this** Actor as one
named tool rather than loading the whole store.

**Claude Desktop or Claude Code** - add a custom connector with the URL:

```
https://mcp.apify.com?tools=vital_tuxedo/remote-jobs-feed
```

**Any other MCP client** (Cursor, VS Code, ChatGPT developer mode, your own
agent) - add the server to its config:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=vital_tuxedo/remote-jobs-feed",
      "headers": { "Authorization": "Bearer <APIFY_TOKEN>" }
    }
  }
}
```

Drop the `headers` block to use OAuth instead: the browser opens once so you
can sign in to Apify and approve access. Then ask in plain language:

> *Find senior remote data engineering roles open to applicants in Germany that were posted this week, with their salary ranges.*

Your assistant starts the run, waits for it and reads the dataset back. The
per-event price above is the whole cost - going through MCP adds nothing.

**No Apify account at all?** This Actor is built to the agentic-payments
criteria (pay-per-event, no platform-usage charge, no Standby), so an agent
holding USDC on Base can buy a prepaid Apify token at `https://agi.apify.com`
over x402 and run it with no account and no signup.

### FAQ

**Is this allowed?** Yes, and it is checked every run. Himalayas publishes
this API for public use and says so on its API page; the only conditions are
to link back to the job's URL on Himalayas and to name Himalayas as the
source - both are on every row - and not to submit the jobs to Jooble, Neuvoo,
Google Jobs or LinkedIn Jobs. Before reading anything the Actor re-fetches
`himalayas.app/robots.txt` and the API page, and if the feed path is ever
disallowed or the grant sentence disappears it stops with nothing read and
nothing charged.

**Can I republish the rows on my own site?** That is what the API is for -
"backfill other remote job boards" is the venue's own first example. Keep
`source_url` as a link and name Himalayas as the source. Do not push them to
the aggregators the licence names.

**Why 20 jobs a page?** The venue's maximum. The Actor reads pages one at a
time with a short pause; the whole feed is about 5,000 requests and about
half an hour.

**Does search return everything?** Up to 5,000 jobs per keyword, the venue's
cap. For more than that, browse the whole feed and filter locally.

**Why is a salary `null`?** The employer did not publish one. When they did,
`min_salary`, `max_salary`, `currency` and `salary_period` carry it as
numbers and codes, not as a string.

**What does the run summary say?** The permission check result, pages read,
jobs seen, duplicates skipped, rows pushed, per-keyword counts in search
mode, and `stoppedBy` when a cap or a charge limit ended the run.

### Running locally

```
npm install
npm start
```

With no `INPUT.json` under `storage/key_value_stores/default/` the run uses
the schema defaults: browse, 1,000 rows. Off the platform nothing is charged
and every row is written under `storage/datasets/default/`.

# Actor input Schema

## `mode` (type: `string`):

browse reads the whole Himalayas feed from newest to oldest, 20 jobs a page, and never returns the same job twice. search asks the search endpoint for each keyword below with the filters, up to 5,000 jobs per keyword (the venue's cap).

## `queries` (type: `array`):

One keyword per line, e.g. 'react engineer' or 'product designer'. A job matched by two keywords is one row. Leave empty in search mode to search with the filters alone.

## `country` (type: `string`):

ISO alpha-2 code, a country name or a slug, e.g. US, Germany, united-kingdom.

## `worldwide` (type: `boolean`):

Keep only jobs open to applicants anywhere.

## `seniority` (type: `array`):

One or more levels.

## `employmentType` (type: `array`):

One or more types.

## `company` (type: `string`):

One or more canonical company slugs, comma separated, e.g. linear or linear,vercel.

## `timezone` (type: `string`):

A UTC offset such as -5, UTC-5 or UTC+05:30.

## `sort` (type: `string`):

Order of the search results: most recent first, most relevant, salary ascending or descending, or company name.

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

Keep the job's full HTML description on each row. It costs no extra request; turn it off for a lighter dataset.

## `maxRows` (type: `integer`):

Stop after this many jobs have been pushed. 0 means unbounded - in browse mode that is the whole feed, about 100,000 jobs. Each unique job is one job-row event.

## `timeoutSecs` (type: `integer`):

A request that does not answer within this many seconds is retried twice with backoff, then recorded as an error and the run ends.

## Actor input object example

```json
{
  "mode": "browse",
  "queries": [
    "python",
    "product designer"
  ],
  "country": "",
  "worldwide": false,
  "seniority": [],
  "employmentType": [],
  "company": "",
  "timezone": "",
  "sort": "recent",
  "includeDescription": true,
  "maxRows": 1000,
  "timeoutSecs": 20
}
```

# Actor output Schema

## `jobs` (type: `string`):

Every job read, one row each, with title, company, salary, seniority, categories, dates, the apply link and the source link on Himalayas.

## `runSummary` (type: `string`):

Counts for the run: the permission check, pages read, jobs seen, duplicates skipped, rows pushed, per-keyword counts in search mode, and what stopped the run if a cap did.

# 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 = {
    "queries": [
        "python",
        "product designer"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("vital_tuxedo/remote-jobs-feed").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 = { "queries": [
        "python",
        "product designer",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("vital_tuxedo/remote-jobs-feed").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 '{
  "queries": [
    "python",
    "product designer"
  ]
}' |
apify call vital_tuxedo/remote-jobs-feed --silent --output-dataset

```

## MCP server setup

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

```

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/wA0MiBzbuSyoRV7Uf/builds/naAghQ0pHjUUHbA0a/openapi.json
