# Himalayas Jobs History (`hyperbach/himalayas-jobs-history`) Actor

Every remote job on himalayas.app, kept after it expires — with the employer's real website domain (not a board slug), salary band, and when and why each posting closed (filled early vs ran to expiry). A continuously tailed archive served at database speed, never Cloudflare-blocked.

- **URL**: https://apify.com/hyperbach/himalayas-jobs-history.md
- **Developed by:** [Hyperbach](https://apify.com/hyperbach) (community)
- **Categories:** Jobs
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$4.00 / 1,000 results

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

## Himalayas Jobs History

**Not just another Himalayas scraper.** Every remote job comes with the *company behind it* — resolved to its **real website domain**, not a board slug — plus the one thing a live scrape can never give you: **when and why each posting closed**. A continuously tailed archive of himalayas.app, served at database speed.

### Why this archive, not a live scrape

- **The company behind every job — resolved to its real domain.** Not `himalayas.app/companies/stripe` like every other Himalayas scraper (we ran all 13 and checked — none of them do this): the employer's *actual* website (`stripe.com`), name, and logo. Turn a hiring signal into a company you can act on — link postings to companies, enrich a CRM, or dedupe by employer.
- **Postings that are gone, with the reason.** `status=gone` returns removed listings and `gone_reason` says whether they were filled early or ran to expiry — the part no live scraper can give you, because it only sees what's open right now.
- **Change history.** Salary and deadline moves are recorded as dated transitions rather than overwritten, so you can chart how an advertised band drifted over months.
- **Incremental by design.** Leave `postedSince` empty and each run returns only the postings that appeared since the last one — the Actor tracks its own cursor.
- **Database speed, and unblockable.** You read our maintained archive, not himalayas.app, so a run answers as a query and can never be rate-limited or Cloudflare-challenged.

### Who it's for

- **Sales & lead-gen teams** — every job resolves to the employer's real domain — a hiring signal becomes a company + website you can prospect, not just a name.
- **Recruiters & talent researchers** — time-to-fill by role, repost patterns, which employers churn the same position.
- **Compensation analysts** — how advertised salary bands move over time across roles and regions.
- **Job-board & SaaS builders** — a clean, deduplicated remote-jobs feed with employer identity and an archive envelope to build on.

### Quick start

**Basic — newest postings**

```json
{
  "maxItems": 10
}
```

**Filtered**

```json
{
  "keyword": "engineer",
  "salaryMin": 120000,
  "remoteOnly": true,
  "maxItems": 50
}
```

**Notification mode — only what appeared since the last run**

```json
{
  "postedSince": ""
}
```

### Output

One record per posting:

| field | meaning |
|---|---|
| `job_id` | Stable unique key for the posting, `<source>:<id>`. Deduplicate across runs and join to your own data on this. |
| `url` | Canonical posting URL. |
| `title` | Job title. |
| `company` | Employer name as the board lists it. |
| `company_domain` | The employer's own web domain, resolved from the posting. |
| `company_slug` | The board's identifier for the employer. |
| `company_logo_url` | Employer logo, when the board provides one. |
| `location_restriction` | Where the posting says the role may be based. |
| `employment_type` | Full time, contract, and so on, as declared by the employer. |
| `categories` | Category tags the board assigned to the posting. |
| `description` | Full posting description. |
| `salary_min` | Lower bound of the advertised band. |
| `salary_max` | Upper bound of the advertised band. |
| `salary_currency` | ISO currency of the advertised band. |
| `salary_unit` | Period the band refers to (e.g. `YEAR`, `HOUR`). |
| `posted_at` | When the posting first appeared. |
| `first_seen_at` | When our archive first captured it. |
| `expires_at` | The board's own expiry date, when it exposes one. |
| `status` | `live` while listed, `gone` once removed. |
| `gone_reason` | `filled` if removed before its expiry date, `expired` if it ran to term. |
| `gone_at` | The date the posting was first observed gone. Null while it is live. Naukri overwrites its expired list nightly, so this is only knowable to whoever was watching that day. |
| `apply_url` | Where to apply for the role. |
| `enriched` | Whether salary, employment type and employer domain have been resolved yet — a posting is returned as soon as it is found, enriched or not. |

Example record:

```json
{
  "job_id": "himalayas_jobs:companies/clera/jobs/founding-full-stack-ios-engineer",
  "url": "https://himalayas.app/companies/clera/jobs/founding-full-stack-ios-engineer",
  "title": "Founding Full-Stack iOS Engineer",
  "company": "Clera",
  "company_domain": "getclera.com",
  "company_slug": "clera",
  "company_logo_url": "",
  "location_restriction": "United Kingdom",
  "employment_type": "Full Time",
  "categories": [
    "Founding-Fullstack-Engineer",
    "Founding-Software-Engineer",
    "IOS-Engineer",
    "IOS-Software-Engineer",
    "Founding-CTO"
  ],
  "description": "<h3>About the Role</h3><p>This is a founding engineering opportunity at a Y Combinator–backed consumer wearable startup operating at the intersection of biometrics, emotional intel …(truncated for display)",
  "salary_min": 150000.0,
  "salary_max": 150000.0,
  "salary_currency": "USD",
  "salary_unit": "YEAR",
  "posted_at": "2026-08-02 05:17:00+00",
  "first_seen_at": "2026-08-02 07:40:06.5383+00",
  "expires_at": "2026-10-01 05:17:00+00",
  "status": "live",
  "gone_reason": null,
  "gone_at": null,
  "apply_url": "https://himalayas.app/companies/clera/jobs/founding-full-stack-ios-engineer",
  "enriched": true
}
```

### Pricing

**$0.004 per result** — pay only for the postings a run returns, with **no start fee**. The premium of the per-source archives: the only one carrying the employer's real website domain *and* a salary band *and* classified expiry history (filled vs expired), over the full himalayas.app board. Competing Himalayas scrapers run $1–3 per 1,000 with none of the three.

### Usage patterns

- **Turn the feed into a company list** — Every posting carries the employer's real domain, name and logo — filter and dedupe by company to get a live list of hiring companies with their websites, not just job rows.
- **What closed, and why** — Set `status=gone` to study removals; `gone_reason` splits filled-early from ran-to-expiry.
- **Incremental sync** — Leave `postedSince` empty; each run continues from the previous one's cursor — no duplicates, nothing skipped.
- **Salary drift** — Pull a role over time and read `salary_min`/`salary_max` per observation to chart how the advertised band moved.

### Input configuration

| field | type | default | what it does |
|---|---|---|---|
| `keyword` | `string` |  | Matches job title or category. |
| `company` | `string` |  | Employer name as the board lists it. Partial matches work. |
| `postedSince` | `string` |  | ISO timestamp. Leave empty and the Actor remembers where it stopped, returning only new postings each run. |
| `goneSince` | `string` |  | Only postings observed dead at or after this ISO timestamp. The query this archive exists to answer. |
| `status` | `live` / `gone` / `any` | `"live"` | 'Gone' returns postings that have been removed, with why — the part no live scraper can give you. |
| `location` | `string` |  | Substring match on the posting's location. |
| `remoteOnly` | `boolean` | `false` | Only postings the employer marks as remote. |
| `descriptionSearch` | `string` |  | Substring match inside the job description. |
| `excludeTitle` | `string` |  | Drop postings whose title contains this. |
| `maxItems` | `integer` | `500` | Upper bound on results returned in a single run. |
| `fullRefresh` | `boolean` | `false` | By default each run returns only what appeared since your last one, so a schedule never re-delivers the same page. Tick this to ignore that bookmark and re-pull the full result set for your filters — and it clears the stored cursor, so your next ordinary run starts clean. |
| `salaryMin` | `integer` |  | Matches any posting whose advertised band reaches this figure. A $10-35/hr band matches a request for 35. |
| `enrichedOnly` | `boolean` | `false` | Return only postings whose salary, employment type and description have been parsed. Off by default: an unenriched record still carries title, company, location and dates, and withholding it trades a real answer for a slower better one. |

### FAQ

**How is this different from the other Himalayas scrapers?**

They read the same public feed and return live listings with the company *name* only. This one adds two things none of them have: the employer's **real website domain** on every job, and **expiry history** (`status=gone` + `gone_reason`) for postings after they close.

**I get no results.**

Filters combine with AND. Loosen `keyword` or `salaryMin`, or set `status=any` to include gone postings.

**Will I see the same job twice?**

Not in notification mode — leave `postedSince` empty and each run continues where the last one stopped.

**Is this live?**

It is a continuously maintained archive: new postings appear within hours of going up, and closed ones stay with their disappearance recorded.

### Integration

#### JavaScript

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('hyperbach/himalayas-jobs-history').call({"maxItems": 10});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

#### Python

```python
from apify_client import ApifyClient
client = ApifyClient('YOUR_TOKEN')
run = client.actor('hyperbach/himalayas-jobs-history').call(run_input={'maxItems': 10})
items = client.dataset(run['defaultDatasetId']).list_items().items
```

#### CLI

```bash
apify call hyperbach/himalayas-jobs-history --input '{"maxItems": 10}'
```

#### REST

```bash
curl -X POST "https://api.apify.com/v2/acts/hyperbach~himalayas-jobs-history/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H 'Content-Type: application/json' -d '{"maxItems": 10}'
```

### Support

support@hyperbach.com

*This page is generated from the Actor's schemas and a live sample — it cannot describe a field the Actor does not have.*

# Actor input Schema

## `keyword` (type: `string`):

Matches job title or category.

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

Employer name as the board lists it. Partial matches work.

## `postedSince` (type: `string`):

ISO timestamp. Leave empty and the Actor remembers where it stopped, returning only new postings each run.

## `goneSince` (type: `string`):

Only postings observed dead at or after this ISO timestamp. The query this archive exists to answer.

## `status` (type: `string`):

'Gone' returns postings that have been removed, with why — the part no live scraper can give you.

## `location` (type: `string`):

Substring match on the posting's location.

## `remoteOnly` (type: `boolean`):

Only postings the employer marks as remote.

## `descriptionSearch` (type: `string`):

Substring match inside the job description.

## `excludeTitle` (type: `string`):

Drop postings whose title contains this.

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

Upper bound on results returned in a single run.

## `fullRefresh` (type: `boolean`):

By default each run returns only what appeared since your last one, so a schedule never re-delivers the same page. Tick this to ignore that bookmark and re-pull the full result set for your filters — and it clears the stored cursor, so your next ordinary run starts clean.

## `salaryMin` (type: `integer`):

Matches any posting whose advertised band reaches this figure. A $10-35/hr band matches a request for 35.

## `enrichedOnly` (type: `boolean`):

Return only postings whose salary, employment type and description have been parsed. Off by default: an unenriched record still carries title, company, location and dates, and withholding it trades a real answer for a slower better one.

## Actor input object example

```json
{
  "status": "live",
  "remoteOnly": false,
  "maxItems": 500,
  "fullRefresh": false,
  "enrichedOnly": false
}
```

# Actor output Schema

## `results` (type: `string`):

All scraped records in the default dataset. One record per posting:

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("hyperbach/himalayas-jobs-history").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("hyperbach/himalayas-jobs-history").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call hyperbach/himalayas-jobs-history --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=hyperbach/himalayas-jobs-history",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/Tv4aFSbUJ1wD0h0za/builds/5pfrFn05QB2nwxjSS/openapi.json
