Himalayas Remote Jobs API: Salary, Seniority, Country Filters avatar

Himalayas Remote Jobs API: Salary, Seniority, Country Filters

Pricing

from $0.70 / 1,000 job postings

Go to Apify Store
Himalayas Remote Jobs API: Salary, Seniority, Country Filters

Himalayas Remote Jobs API: Salary, Seniority, Country Filters

Remote job listings from the free Himalayas jobs API: title, company, employment type, seniority, country and timezone restrictions, salary normalised to a yearly figure, posting date, age in days and apply link. Filter by keyword, country, seniority, contract type, company or pay. UTC dates.

Pricing

from $0.70 / 1,000 job postings

Rating

0.0

(0)

Developer

Samat Makatov

Samat Makatov

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Categories

Share

Remote job listings from the free Himalayas jobs API: title, company, employment type, seniority, country and timezone restrictions, salary normalised to a yearly figure, posting date, age in days and apply link. Filter by keyword, country, seniority, contract type, company or pay. UTC dates.

One row per job posting, read from the public jobs API of Himalayas, a remote-work job board. Every row carries the employer, the contract type, the levels the board assigned, the countries a candidate may work from, the UTC offsets the hours cover, the pay as the employer published it plus the same figures annualised, the posting and expiry dates, the job families, the advert text and the link to apply. No API key, no account, no cookie, no proxy and no browser — the source answers plain JSON.

Two things this actor adds on top of the board's own search: a repeat-run mode (onlyNew plus sinceHours, so a scheduled run reports only what appeared since the last one) and comparable pay (salaryMinAnnual / salaryMaxAnnual with the minAnnualSalary filter the source has none for). Every filter is also re-checked on each row before it is written, because the source answers the unfiltered board when it meets a parameter it does not recognise.

Need it tailored to your workflow? Missing a field, a filter, another source or a different output format? Open an issue and describe what you need — we read every request and adapt the actor.

Use cases

  • Fill a job board or a newsletter: run feed mode with sinceHours: 24 and onlyNew on a schedule and get only the postings published since yesterday, descriptions included as plain text.
  • Source candidates in one market: a keyword plus countries and seniority, with excludeWorldwide so every row really is restricted to the country you report on.
  • Benchmark pay: onlyWithSalary with salaryCurrency and minAnnualSalary, then read salaryMinAnnual / salaryMaxAnnual — hourly, daily, weekly, fortnightly, monthly and quarterly figures are converted to a year first, so they can be sorted and averaged.
  • Watch employers: put company slugs into companies and schedule it with onlyNew to see every new opening of a competitor or a target employer.
  • Feed an agent or an LLM: descriptionFormat: "text" gives the whole advert without markup; "none" keeps a 1 000-row dataset small when you only need the metadata.
  • Contract-market view for freelancers: employmentTypes: ["Contractor"] with sinceHours: 168 for everything that went up in the last week.

Input

Nothing is required: with no input at all the actor returns the newest postings of the board. Two modes do two different jobs — search asks the board's own search (keyword and filters, paged), feed walks the whole board newest first (for mirroring and alerts).

Strict vs forgiving. mode, seniority, employmentTypes, sort and descriptionFormat are closed lists: Apify refuses a value outside the list before the run starts, with the allowed values in the error, so write them exactly as listed below. countries, companies, salaryCurrency and parentCategories are free text, and each is read its own way: countries ignores case, spacing, hyphens and accents, accepts the spellings listed in Reference, and refuses any other value with the closest names ("did you mean …?") instead of swapping in a market you did not ask for; companies is lower-cased and then matched exactly, so a display name with spaces finds nothing and the run reports it in its status; salaryCurrency is upper-cased and refused only when it is not three letters — a code the source never uses simply returns no rows; parentCategories is matched case-insensitively on the rows, and a value that matched nothing is named in the run status together with the families the run did see.

FieldTypeDefaultAllowed values / notes
modestringsearchsearch (keyword + filters) or feed (whole board, newest first). Strict list.
querystring—Free text the board searches in titles, descriptions and categories (python, product designer, kubernetes). Sent as typed. Ignored in feed mode.
countriesstring[]—Up to 10 country names or two-letter codes: United States, us, Germany, DE, USA, UK, Czech Republic. Asked for one after another, rows merged and de-duplicated; requestedCountry says which value found a row. See Countries.
worldwideOnlybooleanfalseKeep only postings with no country restriction at all. Cannot be combined with excludeWorldwide.
excludeWorldwidebooleanfalseDrop postings with no country restriction, so a country report is not blurred by them.
senioritystring[]—Entry-level, Mid-level, Senior, Manager, Director, Executive. Several = OR. Strict list.
employmentTypesstring[]—Full Time, Part Time, Contractor, Temporary, Intern, Volunteer, Other. Several = OR. Strict list.
companiesstring[]—Up to 20 company slugs — the short name in a job URL (canonical, gitlab, lemon-io). Lower-cased, then matched exactly; a display name with spaces finds nothing and the run says so.
timezoneOffsetnumber—−12 to 14, half and quarter hours allowed (-5, 1, 5.5). Postings that list no timezone are kept, because they limit nobody.
sortstringrecentrecent, relevant, salaryDesc, salaryAsc. search mode only — feed is always newest first. Strict list. See Sort orders.
onlyWithSalarybooleanfalseDrop postings with no published figure.
salaryCurrencystring—Three-letter ISO 4217 code (USD, EUR, GBP, PLN). Case does not matter. No currency conversion happens, so this is how you compare pay.
minAnnualSalarynumber—Keep postings whose salaryMaxAnnual is at least this much. See Pay periods.
sinceHoursnumber—1–8760. Freshness window from the run's start, UTC. In the newest-first orders paging stops at the window.
includeExpiredbooleanfalseKeep postings past their expiry date (isExpired, expiresAt). Off by default.
onlyNewbooleanfalseRemember the job URLs this run writes and, next run of the same actor or task, write only postings not written before.
parentCategoriesstring[]—Up to 10 job families, matched on the row: Developer, Operations, Design, Marketing, Sales, Data Science… See Job families. A value that matched nothing is named in the run status.
descriptionFormatstringtexttext (markup stripped), html (as the source sends it), none (both columns empty). Strict list.
maxItemsnumber501–1000. Hard cap on rows, and therefore on cost.
fieldsstring[]allKeep only these columns, in this order. title, companyName, url, postedAt, fetchedAt and sourceMode are always kept — the ones you do not list come first, and one you do list moves to the position you gave it. Unknown names are reported in the run status.

Reference

Countries

countries takes the 201 country names the board itself writes into a posting, or their ISO-3166 alpha-2 codes (de, US, gb). Case, spaces, hyphens, underscores and accents are ignored, so united states, United-States and Curacao all work. These extra spellings are accepted as well: USA, U.S., United States of America; UK, Great Britain, Britain; Czech Republic (→ Czechia); Russia (→ Russian Federation); Holland, The Netherlands; Korea, Republic of Korea (→ South Korea); Ivory Coast (→ Côte d'Ivoire); Cape Verde (→ Cabo Verde); Swaziland (→ Eswatini); Macedonia (→ North Macedonia); Syria, Palestine, Vatican, Bosnia, DR Congo / DRC, UAE / Emirates, Türkiye, Brasil, Deutschland, Italia, España, Polska, Viet Nam, Antigua, The Gambia, The Bahamas, The Philippines, Saint Helena, Republic of the Congo.

Anything else is refused before any request is made, with the closest names in the error — Germny comes back as Unknown countries "Germny" (did you mean "Germany"?). That is deliberate: a near miss is another market as often as a typo (Niger / Nigeria, Iraq / Iran), and a silently swapped country would hand you the wrong report.

Worldwide postings carry an empty countries list and isWorldwide: true. They match every country filter (anyone anywhere may apply) unless you switch excludeWorldwide on.

Seniority

ValueMeaning
Entry-levelgraduates and juniors
Mid-levela few years of experience
Seniorsenior individual contributors
Managerpeople management
Directorheads of department
ExecutiveC-level and VP

One posting can carry several levels (["Mid-level", "Senior"]), and a row matches when any of its levels is one you asked for.

Employment types

Full Time, Part Time, Contractor (freelance and B2B contracts), Temporary, Intern, Volunteer, Other. One value per posting, written to employmentType — mind the capitals and the space in Full Time.

Sort orders

ValueOrder
recentnewest first (the default; makes sinceHours and repeat runs predictable)
relevantthe board's own keyword ranking
salaryDeschighest published pay first
salaryAsclowest published pay first

The order decides which postings you see first when maxItems cuts the answer. The board's own ordering is not strict — a recent page can carry an older posting between newer ones — so paging stops at sinceHours only once a whole page is past the window.

Pay periods

The board publishes pay in the employer's own currency and period. salaryMinAnnual / salaryMaxAnnual convert the figures to a year with these factors, and nothing else:

salaryPeriod×
hourly2080
daily260
weekly52
fortnightly26
monthly12
quarterly4
annual1

No exchange rate is ever applied, so set salaryCurrency whenever you compare or sort by pay. A period outside the table leaves both annualised columns empty.

Job families

parentCategories is matched case-insensitively against the column of the same name. The families seen in live responses on 2026-10-07: Content Creator, Customer Service, Data Science, Design, Developer, Education, Finance, Hardware Engineer, Healthcare, Human Resources, Legal, Management, Marketing, Operations, Product, Sales. The board publishes no closed list, so this filter is applied to the rows after fetching and a value that matched nothing is named in the run status together with the families the run did see — the words in the column are always the ones that work.

Examples

Senior Python roles a candidate in the US may take — tech recruiting and sourcing.

{ "mode": "search", "query": "python", "countries": ["United States"], "seniority": ["Senior"], "excludeWorldwide": true, "sort": "recent", "maxItems": 15 }

Worldwide postings that publish a salary, highest pay first — compensation research.

{ "mode": "search", "worldwideOnly": true, "onlyWithSalary": true, "sort": "salaryDesc", "maxItems": 15 }

Remote design jobs open to candidates in Germany — an EU hiring report; change countries for another market.

{ "mode": "search", "query": "designer", "countries": ["Germany"], "excludeWorldwide": true, "sort": "recent", "maxItems": 10 }

Contract openings from the last seven days — freelancers and staffing agencies; set sinceHours: 24 for a daily alert.

{ "mode": "search", "employmentTypes": ["Contractor"], "sinceHours": 168, "sort": "recent", "maxItems": 15 }

Everything posted on the board in the last two days, no keyword — board operators and alert feeds; add onlyNew and schedule it.

{ "mode": "feed", "sinceHours": 48, "descriptionFormat": "none", "onlyNew": true, "maxItems": 20 }

Every current opening of one employer — the slug is the short name in a job URL.

{ "mode": "search", "companies": ["canonical"], "sort": "recent", "maxItems": 10 }

Engineering roles paying at least 100 000 USD a year, four columns only — salary benchmarking.

{ "mode": "search", "query": "engineer", "onlyWithSalary": true, "salaryCurrency": "USD", "minAnnualSalary": 100000, "sort": "salaryDesc", "fields": ["title", "companyName", "salaryMaxAnnual", "salaryCurrency"], "maxItems": 10 }

Output

One row per posting. A real row from a cloud run (long arrays and the advert text trimmed with …):

{
"title": "Software Engineer",
"companyName": "ElitevoraSys LLC",
"url": "https://himalayas.app/companies/elitevorasys-llc/jobs/software-engineer",
"postedAt": "2026-09-21T03:43:48.000Z",
"fetchedAt": "2026-10-07T20:17:31.407Z",
"sourceMode": "search",
"companySlug": "elitevorasys-llc",
"companyLogoUrl": "https://cdn-images.himalayas.app/3pc0s39uob814yxkuwy550qy0jk9",
"employmentType": "Full Time",
"seniority": ["Senior"],
"countries": ["United States"],
"countryCount": 1,
"isWorldwide": false,
"timezoneOffsets": [-11, -10, -9.5, -9, -8, "…"],
"requestedCountry": "United States",
"salaryMin": 160000,
"salaryMax": 240000,
"salaryPeriod": "annual",
"salaryCurrency": "USD",
"salaryMinAnnual": 160000,
"salaryMaxAnnual": 240000,
"hasSalary": true,
"expiresAt": "2026-10-17T15:00:23.000Z",
"isExpired": false,
"ageDays": 16.69,
"categories": ["Software-Engineer", "Software-Developer", "…"],
"parentCategories": ["Developer"],
"excerpt": "About Us ElitevoraSys is a modern engineering consultancy focused on building high-performance operational platforms …",
"descriptionText": "About Us\nElitevoraSys is a modern engineering consultancy focused on building high-performance operational platforms, automation pipelines, and data-driven workflows …",
"descriptionHtml": null,
"source": "himalayas.app"
}
FieldTypeMeaning
titlestringPosting headline. Always filled.
companyNamestringHiring company. Always filled.
urlstringThe job page on the board — where a candidate applies, and the id rows are de-duplicated by. Always filled.
postedAtstring | nullPublication time, UTC ISO-8601.
fetchedAtstringWhen this run read the posting, UTC ISO-8601. Always filled.
sourceModestringsearch or feed — which endpoint found the row. Always filled.
companySlugstring | nullShort company name from the URL — the value for companies.
companyLogoUrlstring | nullAddress of the company logo, as a value; the actor never downloads it.
employmentTypestring | nullContract type (see Employment types).
senioritystring[]Levels the board assigned; can hold several.
countriesstring[]Countries the employer can hire in. Empty = open worldwide.
countryCountnumberSize of countries; 0 for a worldwide posting.
isWorldwidebooleanTrue when the posting names no country.
timezoneOffsetsnumber[]UTC offsets the hours cover (half and quarter hours occur). Empty = no timezone limit.
requestedCountrystring | nullWhich countries value returned this row; null when the run asked for no country.
salaryMin / salaryMaxnumber | nullPay exactly as published, in the period of salaryPeriod.
salaryPeriodstring | nullPeriod of the published figures, as the source words it: hourly, daily, weekly, fortnightly, monthly, quarterly, annual (see Pay periods).
salaryCurrencystring | nullISO 4217 code of the published figures. Never converted.
salaryMinAnnual / salaryMaxAnnualnumber | nullThe same pay for a year, same currency — the comparable columns, and what minAnnualSalary filters on.
hasSalarybooleanTrue when at least one figure was published.
expiresAtstring | nullWhen applications close, UTC ISO-8601.
isExpiredbooleanTrue when the expiry date has passed; such rows need includeExpired.
ageDaysnumber | nullDays between postedAt and this run, two decimals.
categoriesstring[]Narrow tags the board put on the posting.
parentCategoriesstring[]Job families — what parentCategories matches against.
excerptstring | nullFirst sentences of the advert; filled whatever descriptionFormat is.
descriptionTextstring | nullWhole advert, markup stripped (descriptionFormat: "text").
descriptionHtmlstring | nullWhole advert as the source sends it (descriptionFormat: "html").
sourcestringAlways himalayas.app.

Dataset views: Remote jobs (job, company, contract, level, worldwide, countries, annualised pay, posted, days old, link), Pay, as published and annualised, Where the job may be done, and how the row was found.

With fields the row keeps only the columns you name, in that order; title, companyName, url, postedAt, fetchedAt and sourceMode are always kept, the ones you did not name coming first.

A run also writes a SUMMARY record to its key-value store: how many requests and pages it made, how many postings it read, how many rows each filter dropped, the job families it saw, whether the request budget or the freshness window ended it, and the final status message.

Use it from code / agents

curl -X POST "https://api.apify.com/v2/acts/yadroo~himalayas-remote-jobs/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"query":"python","countries":["United States"],"seniority":["Senior"],"maxItems":20}'
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('yadroo/himalayas-remote-jobs').call({ query: 'python', countries: ['United States'], seniority: ['Senior'], maxItems: 20 });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("yadroo/himalayas-remote-jobs").call(run_input={"query": "python", "countries": ["United States"], "seniority": ["Senior"], "maxItems": 20})
items = client.dataset(run["defaultDatasetId"]).list_items().items

MCP: add https://mcp.apify.com to Claude / Cursor / any MCP client and call the yadroo/himalayas-remote-jobs tool with the same JSON input. For agents: mode, seniority, employmentTypes, sort and descriptionFormat are validated by the platform before the run starts, so an off-list value comes back as an input error with the allowed values, not as an empty dataset.

Pricing

Pay per event: $0.001 per run start + $0.001 per job row. Every run is charged the start event, also a run that finds nothing. Every row written to the dataset is charged once — there are no "not found" marker rows in this actor, so you only pay for postings.

RunEventsCost
20 rows (one keyword, one country)1 start + 20 rows$0.001 + $0.020 = $0.021
50 rows (the default maxItems)1 start + 50 rows$0.001 + $0.050 = $0.051
1 000 rows (the maximum)1 start + 1 000 rows$0.001 + $1.000 = $1.001
an hourly onlyNew alert that finds nothing new1 start only$0.001

Paid Apify plans get the usual tier discount on the row event (Bronze −10 %, Silver −20 %, Gold and above −30 %); the start event is flat.

Keeping it cheap: maxItems is a hard cap, sinceHours narrows a scheduled run to what is new in the window, and onlyNew stops you paying twice for a posting you already have. The run also stops by itself at the Maximum cost per run you set and keeps every row you already paid for, saying so in its status ("Stopped at your spending limit: N rows delivered").

Limits & FAQ

  • Freshness. The board refreshes roughly once a day, so two runs an hour apart usually see the same postings. A sinceHours under 24 can legitimately come back empty; that is not an error, and the status says how many postings were read.
  • Pace. The actor makes one request per second to one host through a single token bucket, retries included — no numeric rate limit is published, only "429 → wait 60 seconds", which the actor honours (it also follows a Retry-After header). One request returns at most 20 postings, so the ceiling is about 60 requests and 1 200 postings a minute; a run of 50 consecutive requests returned 1 000 postings in 49 seconds (~61 requests and ~1 220 rows a minute) with no 429 and no slow-down, measured 2026-10-07, so the pace is the bucket, not the source. A 50-row run takes 5–10 seconds including start-up; a 1 000-row run about 55 seconds.
  • Request budget. One run makes at most 60 source requests (≈ 1 200 postings scanned). That is what stops a narrow row-side filter (a rare currency plus a high minAnnualSalary) from walking the whole board; when the budget ends a run, the status says so and names the rows saved. A 1 000-row run needs at least 50 requests, so it fits — but only if the filters do not discard most of each page.
  • Run timeout. The default run timeout is 900 s and the largest allowed input finishes well inside it. A run that would still run out of time stops early by itself, keeps every row it has read and ends SUCCEEDED with "Stopped before the run timeout: N rows saved".
  • totalCount is not your row count. The number the source reports is its own; it does not match what a filter really yields, and it is not written to the rows. The real end of a list is an empty page, which is where paging stops — a short page in the middle is normal here.
  • Repeated postings. A paged search on this source returns some postings on two neighbouring pages, and two country filters can both return the same posting. Rows are de-duplicated by job URL, so you are never charged twice for the same posting inside a run.
  • Filters are verified on the row. The source answers the unfiltered board when it meets a parameter it does not recognise, so country, seniority, contract type, company, timezone, salary, job family, freshness and expiry are all checked again on each row before it is written. The status says how many rows each filter dropped.
  • Salary coverage. Measured on 2026-10-07: about four postings in ten publish a pay figure on the plain newest-first feed, more on a narrow keyword search (about two thirds of the senior-Python-in-the-US rows). So onlyWithSalary shrinks a run, by how much depends on the slice. salaryPeriod can be set while the figures themselves are null — hasSalary tells the two apart. Combine onlyWithSalary with sort: "salaryDesc" so the paid-up rows arrive first instead of being hunted page by page.
  • No currency conversion. Pay stays in the employer's currency. salaryCurrency is therefore part of any pay comparison, and minAnnualSalary only means something together with it.
  • Expired adverts are dropped unless includeExpired is on; the board keeps some of them in the feed after their expiry date.
  • Descriptions are the employer's own HTML as the board sanitises it. text strips the markup, html keeps it, none leaves both columns out.
  • Empty result vs error. An unknown country, an impossible combination of the two worldwide switches or a malformed currency code fails the run before any request, with the fix in the message. A filter that simply matched nothing is a successful run with zero rows and a status that names the filter.
  • No personal data. These are employer postings: no candidate or recruiter names, e-mails or phone numbers are collected.

Questions or problems: open an issue on the Issues tab of this actor.


Made by Yadroo. Sibling actors: greenhouse-jobs, workable-jobs, ashby-job-postings, personio-jobs, recruitee-jobs.