# Himalayas Remote Jobs Scraper (`automation-lab/himalayas-remote-jobs-scraper-retry`) Actor

Search and export current Himalayas remote jobs with company, location restrictions, employment type, salary, categories, dates, descriptions, and application URLs.

- **URL**: https://apify.com/automation-lab/himalayas-remote-jobs-scraper-retry.md
- **Developed by:** [Automation Lab](https://apify.com/automation-lab) (community)
- **Categories:** Jobs
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.48 / 1,000 job extracteds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Himalayas Remote Jobs Scraper

Search and export current **Himalayas remote jobs** as structured records for recruiting, job-feed operations, and labor-market analysis.

The Actor reads Himalayas' public jobs feed, follows cursor pagination, and returns useful vacancy fields such as company, candidate-location restrictions, employment type, salary, seniority, categories, description, dates, and application URL.

It supports both broad role or keyword searches and targeted retrieval of current Himalayas job URLs.

### What can you do with this Actor?

- Build a current remote-vacancy feed for a recruiting workflow.
- Search Himalayas jobs by role, company, or category text.
- Retrieve one or more current job records by their public Himalayas URLs.
- Focus analysis by employment type, seniority, candidate location, category, salary, or publication date.
- Export results to JSON, CSV, Excel, Google Sheets, a database, or another Apify integration.
- Schedule recurring runs and compare datasets in your own pipeline to identify new or changed listings.

The Actor produces source-attributed records. It does not apply to jobs, contact candidates, or send alerts by itself.

### Who is it for?

#### Recruiters and talent teams

Build focused shortlists of current remote roles, inspect employer demand, and identify companies hiring for particular skills or seniority levels.

#### Job-board and feed operators

Normalize current Himalayas listings into a dataset that can be exported through Apify's API or connected to an existing ingestion pipeline.

#### Labor-market analysts

Measure advertised locations, employment types, salary ranges, categories, and posting dates across a repeatable sample.

#### Automation developers

Use one stable Actor input and output contract instead of maintaining cursor handling, retries, validation, and normalization in every workflow.

### Why use this Himalayas jobs extractor?

- **Public structured source:** it uses the public Himalayas jobs API rather than parsing fragile page layouts.
- **Cursor pagination:** records are scanned in source order without deprecated offset pagination.
- **Full job rows:** descriptions, company fields, salary fields, restrictions, categories, dates, and links are available in one request path.
- **Consistent filters:** the same optional filters apply to search and explicit-URL inputs.
- **No fabricated rows:** malformed API records and missing or expired URLs are not replaced with guessed data.
- **Bounded execution:** `maxItems` and `maxPages` control result volume and source scanning.
- **Direct HTTP:** no browser or paid proxy is enabled automatically.

### What data does it extract?

| Field | Meaning |
| --- | --- |
| `jobId` | Stable slug from the canonical job URL |
| `title` | Vacancy title |
| `jobUrl` | Canonical public Himalayas job URL |
| `applicationUrl` | Application link exposed by Himalayas |
| `companyName` | Hiring company name |
| `companySlug` | Himalayas company identifier |
| `companyUrl` | Public company profile URL |
| `companyLogoUrl` | Company logo URL when available |
| `excerpt` | Short vacancy summary |
| `description` | Full description when requested |
| `locationRestrictions` | Countries or regions from which candidates may work |
| `timezoneRestrictions` | Accepted UTC offsets when exposed |
| `employmentType` | Full Time, Contract, or another source value |
| `seniority` | Source seniority labels |
| `salaryMin`, `salaryMax` | Advertised salary bounds when present |
| `salaryCurrency` | Advertised currency |
| `salaryPeriod` | Annual, hourly, or another salary period |
| `categories` | Detailed source categories |
| `parentCategories` | Top-level source categories |
| `publishedAt` | ISO 8601 publication time |
| `expiresAt` | ISO 8601 expiry time |
| `source` | `Himalayas` |
| `sourceApiUrl` | Public API surface used by the Actor |
| `scrapedAt` | ISO 8601 extraction time |

Nullable source fields remain `null`. Array fields remain arrays even when empty.

### How to get started

1. Open the Actor in Apify Console.
2. Enter one or more phrases in **Role or keyword queries**, or add current URLs under **Himalayas job URLs**.
3. Add only the filters your workflow needs.
4. Set **Maximum jobs** to the number of matching records you want.
5. Increase **Maximum API pages to scan** for selective queries or filters.
6. Choose whether to include full descriptions.
7. Click **Start**.
8. Open the Dataset tab to preview or export results.

The prefilled input searches for `software engineer`, includes descriptions, and keeps the initial run small.

### Input parameters

| Parameter | Type | Default | Description |
| --- | --- | ---: | --- |
| `searchQueries` | string array | empty | A job matches when at least one phrase appears in its title, company, or categories |
| `startUrls` | URL list | empty | Current public Himalayas job-detail URLs to locate in the feed |
| `employmentTypes` | string array | empty | Case-insensitive partial matches against employment type |
| `seniority` | string array | empty | Match at least one source seniority label |
| `locations` | string array | empty | Match at least one candidate-location restriction |
| `categories` | string array | empty | Match detailed or parent categories |
| `minimumSalary` | number | unset | Require an advertised bound at or above this amount |
| `publishedAfter` | ISO date/time | unset | Keep jobs published at or after the cutoff |
| `includeDescriptions` | boolean | `true` | Include full descriptions in output |
| `maxItems` | integer | `100` | Save at most this many matching jobs, from 1 to 10,000 |
| `maxPages` | integer | `25` | Scan at most this many cursor pages, from 1 to 1,000 |

Multiple values within one filter use OR logic. Different filter groups use AND logic.

For example, two locations and one employment type mean “location A or B, and this employment type.”

### Search by role or keyword

```json
{
  "searchQueries": ["software engineer"],
  "maxItems": 25,
  "maxPages": 25,
  "includeDescriptions": true
}
```

Search checks title, company name, detailed categories, and parent categories.

It is a case-insensitive phrase match, not a semantic ranking engine. A phrase can appear outside the title.

### Retrieve a current job URL

```json
{
  "startUrls": [
    {
      "url": "https://himalayas.app/companies/monetizemore/jobs/business-operations-project-manager-6782873844"
    }
  ],
  "maxItems": 1,
  "maxPages": 2,
  "includeDescriptions": true
}
```

The Actor validates that each URL is a Himalayas company job URL and matches it against canonical URLs in the current public feed.

If a supplied listing expired, was removed, or lies beyond `maxPages`, the Actor logs the missing URL and does not invent a record.

### Build a focused salary feed

```json
{
  "locations": ["United States"],
  "employmentTypes": ["Full Time"],
  "minimumSalary": 100000,
  "maxItems": 100,
  "maxPages": 100,
  "includeDescriptions": false
}
```

`minimumSalary` compares the advertised numeric bounds without converting currencies or salary periods. Filter by one market at a time when values must be directly comparable.

### Output example

A current run returns records shaped like this:

```json
{
  "jobId": "sr-technical-product-marketing-manager-ai-traffic-management-registry",
  "title": "Sr Technical Product Marketing Manager, AI Traffic Management & Registry",
  "jobUrl": "https://himalayas.app/companies/kong/jobs/sr-technical-product-marketing-manager-ai-traffic-management-registry",
  "applicationUrl": "https://himalayas.app/companies/kong/jobs/sr-technical-product-marketing-manager-ai-traffic-management-registry",
  "companyName": "Kong",
  "companySlug": "kong",
  "locationRestrictions": ["United States"],
  "timezoneRestrictions": [],
  "employmentType": "Full Time",
  "seniority": ["Senior"],
  "salaryMin": 153090,
  "salaryMax": 251505,
  "salaryCurrency": "USD",
  "salaryPeriod": "annual",
  "categories": ["Product-Marketing"],
  "parentCategories": ["Marketing"],
  "publishedAt": "2026-09-15T00:00:00.000Z",
  "expiresAt": "2026-11-14T00:00:00.000Z",
  "source": "Himalayas",
  "sourceApiUrl": "https://himalayas.app/jobs/api",
  "scrapedAt": "2026-09-15T06:30:00.000Z"
}
```

Source categories and timestamps change as Himalayas updates its feed.

### How much does it cost to extract Himalayas remote jobs?

The Actor uses pay-per-event pricing:

- one small `start` charge when a run begins;
- one `job` charge for each validated job saved to the dataset.

No job event is charged for filtered-out, duplicate, malformed, missing, or failed records.

At the initial BRONZE rate of $0.0008 per saved job plus a $0.00005 start event, approximate Actor charges are:

| Saved jobs | Approximate Actor charge |
| ---: | ---: |
| 1 | $0.00085 |
| 10 | $0.00805 |
| 100 | $0.08005 |
| 1,000 | $0.80005 |

Higher Apify plans receive lower per-job tiers. Your Apify plan and platform billing may affect the final displayed total; always check the Console pricing panel for the active rate.

### Pagination, limits, and performance

Himalayas currently returns up to 20 jobs per cursor page.

`maxItems` limits saved matches, while `maxPages` limits scanned source pages. Selective filters can require scanning many more records than they save.

The Actor stops when any of these conditions occurs:

- `maxItems` matching jobs have been saved;
- all requested URLs have been found;
- `maxPages` has been scanned;
- the API provides no next cursor;
- the API returns an empty page.

For recurring monitoring, use a publication cutoff and a practical page bound rather than scanning the complete historical feed every time.

### Reliability and failure behavior

Transient network errors, HTTP 429 responses, and server errors receive up to two retries after the initial request with bounded backoff.

The Actor fails rather than returning a false success when the API returns a permanent error, non-JSON content, or an invalid response shape.

The Actor does not retry malformed inputs.

The source website's interactive HTML can present a Cloudflare challenge. This does not affect the public JSON route used by the Actor.

### Recurring monitoring workflow

1. Save a Task with your stable queries and filters.
2. Schedule the Task at the interval your team needs.
3. Export each run's dataset or consume it through the API.
4. Compare `jobUrl`, `publishedAt`, `expiresAt`, salary, and description in your own database.
5. Trigger notifications only for changes that matter to your workflow.

The Actor does not persist a cross-run change history, so your destination remains the source of truth for deduplication and alerts.

### Export and integrations

From the run Dataset tab you can:

- download JSON, CSV, XML, RSS, or Excel;
- send rows to Google Sheets;
- connect a webhook or Make workflow;
- retrieve items through the Apify API;
- pass the dataset ID to another Actor;
- load results into a database or warehouse.

Keep `jobUrl` as the stable source key when merging repeated runs.

### API usage with cURL

Start a run and wait for completion:

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~himalayas-remote-jobs-scraper-retry/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"searchQueries":["data engineer"],"maxItems":10,"maxPages":20}'
```

Keep tokens in environment variables or secret stores, not source code.

### API usage with JavaScript

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/himalayas-remote-jobs-scraper-retry').call({
  searchQueries: ['data engineer'],
  maxItems: 10,
  maxPages: 20,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

### API usage with Python

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/himalayas-remote-jobs-scraper-retry').call(run_input={
    'locations': ['United States'],
    'employmentTypes': ['Full Time'],
    'maxItems': 25,
    'maxPages': 25,
})
items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)
```

### Use through MCP

#### Claude Code

Add the Apify MCP server from your terminal:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/himalayas-remote-jobs-scraper-retry"
```

#### Claude Desktop

Add this server object to Claude Desktop's MCP configuration:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/himalayas-remote-jobs-scraper-retry"
    }
  }
}
```

#### Cursor

Open Cursor Settings, choose **Tools & MCP**, add a remote server named `apify`, and use the same `https://mcp.apify.com?tools=automation-lab/himalayas-remote-jobs-scraper-retry` URL.

#### VS Code

Add the same remote HTTP server URL in VS Code's MCP server settings, then enable the `automation-lab/himalayas-remote-jobs-scraper-retry` tool for your chat session.

Example prompts:

- “Find up to 20 current Himalayas data engineer jobs and return company, allowed locations, salary, and application URL.”
- “Export current full-time Himalayas roles open to candidates in Canada.”
- “Retrieve this current Himalayas job URL and summarize its employment and salary fields.”

### Responsible use and legality

This Actor accesses public vacancy data without logging in.

You are responsible for complying with Himalayas' terms, applicable laws, database rights, privacy obligations, and the rules governing your downstream use.

Use reasonable schedules and limits. Do not republish personal information, create discriminatory hiring decisions, or treat source data as guaranteed accurate.

Job listings can contain names, contact details, or external links supplied by employers. Review data before redistribution.

### Limitations

- Results reflect the public API at run time, not all historical Himalayas records.
- Search and filters are applied client-side to the pages allowed by `maxPages`.
- Explicit URLs must be present within the scanned current feed.
- Salary values are not currency-converted or period-normalized.
- Categories and restrictions are source-provided and may be empty or inconsistent.
- `includeDescriptions: false` returns `description: null`, while keeping the excerpt.
- The Actor does not detect changes across runs or send notifications by itself.
- Source API behavior and fields can change.

### Troubleshooting

#### My search returned no jobs

Increase `maxPages`, simplify the phrase, and temporarily remove filters. Search uses literal case-insensitive phrase matching rather than semantic expansion.

#### A valid URL was not returned

The listing may be expired, removed, or beyond your page bound. Increase `maxPages` and check whether the URL is still present in Himalayas' current public feed.

#### Salary filtering removed too many jobs

Many postings omit structured salary data. Remove `minimumSalary` to include those records, then inspect nullable salary fields downstream.

#### A run failed after retries

Check the run log for the HTTP status or response-shape error. Retry later if Himalayas is temporarily unavailable; do not enable a proxy unless direct API availability has materially changed.

### Frequently asked questions

#### Does this Actor need a Himalayas login or API key?

No. It uses the public jobs feed.

#### Does it need an Apify Proxy?

No. The production route uses direct HTTP and does not automatically enable paid proxy transfer.

#### Can it scrape a company profile?

No. Output includes the company fields attached to each job, but company profiles are outside this Actor's scope.

#### Can it apply to jobs?

No. It exports public listing and application-link data only.

#### Are descriptions included?

Yes by default. Set `includeDescriptions` to `false` for smaller datasets when the excerpt is sufficient.

#### Can I export to a spreadsheet?

Yes. Download CSV or Excel from the Dataset tab, or use the Google Sheets integration.

#### How should I identify duplicates?

Use canonical `jobUrl` as the primary source key. `jobId` is a convenient slug but the URL preserves full source identity.

### Related Automation Lab Actors

For broader remote-market coverage, combine this source-specific feed with:

- [Remote Jobs Multi-Board Feed](https://apify.com/automation-lab/remote-jobs-multi-board-feed) for normalized Remote OK and Remotive records.
- [Remote OK Jobs Feed Scraper](https://apify.com/automation-lab/remoteok-remote-jobs-feed) for a dedicated Remote OK workflow.
- [Working Nomads Jobs Scraper](https://apify.com/automation-lab/working-nomads-jobs-scraper) for another remote-only board.
- [Company Career Page Jobs Scraper](https://apify.com/automation-lab/company-career-page-jobs-scraper) when the input is an employer's own careers page rather than Himalayas.

Keep source names and URLs when merging datasets so buyers can audit where each vacancy originated.

# Changelog

This Actor's version history is a separate document: https://apify.com/automation-lab/himalayas-remote-jobs-scraper-retry/changelog.md

# Actor input Schema

## `searchQueries` (type: `array`):

Keep jobs where at least one phrase appears in the title, company name, or categories.

## `startUrls` (type: `array`):

Optional current Himalayas job-detail URLs. The Actor finds them in the public feed and applies all other filters.

## `employmentTypes` (type: `array`):

Case-insensitive employment-type matches, for example Full Time or Contract.

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

Keep jobs matching at least one seniority label, such as Senior or Junior.

## `locations` (type: `array`):

Keep jobs whose candidate-location restrictions contain at least one supplied country or region.

## `categories` (type: `array`):

Keep jobs matching at least one Himalayas category or parent category.

## `minimumSalary` (type: `number`):

Keep jobs whose advertised minimum or maximum salary reaches this amount. Jobs without salary data are excluded.

## `publishedAfter` (type: `string`):

Optional ISO 8601 date or date-time cutoff for recurring new-job feeds.

## `includeDescriptions` (type: `boolean`):

Include the full description exposed by the Himalayas public feed.

## `maxItems` (type: `integer`):

Maximum matching job records saved to the dataset.

## `maxPages` (type: `integer`):

Safety bound for client-side search and filters. Each page currently contains up to 20 current jobs.

## Actor input object example

```json
{
  "searchQueries": [
    "software engineer"
  ],
  "startUrls": [],
  "includeDescriptions": true,
  "maxItems": 20,
  "maxPages": 10
}
```

# Actor output Schema

## `dataset` (type: `string`):

Validated jobs saved by this run.

# 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 = {
    "searchQueries": [
        "software engineer"
    ],
    "startUrls": [],
    "includeDescriptions": true,
    "maxItems": 20,
    "maxPages": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/himalayas-remote-jobs-scraper-retry").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 = {
    "searchQueries": ["software engineer"],
    "startUrls": [],
    "includeDescriptions": True,
    "maxItems": 20,
    "maxPages": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/himalayas-remote-jobs-scraper-retry").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 '{
  "searchQueries": [
    "software engineer"
  ],
  "startUrls": [],
  "includeDescriptions": true,
  "maxItems": 20,
  "maxPages": 10
}' |
apify call automation-lab/himalayas-remote-jobs-scraper-retry --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/himalayas-remote-jobs-scraper-retry"
        }
    }
}
```

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/pznxSiFaPeQ5hYCPa/builds/bTqQStwasMP2aADbq/openapi.json
