The Himalayas Remote Jobs API is a free public JSON API for remote job data. No API key or authentication is required. Use the browse endpoint when you want the full jobs feed with pagination, and use the search endpoint when you want filtered results by keyword, country, company slug, seniority, employment type, timezone, sort order, or page.
What is the Himalayas Remote Jobs API?
The Himalayas Remote Jobs API is designed for developers, researchers, job board operators, content creators, and AI tools that need machine-readable remote job data from Himalayas.
The API is free to use and requires no authentication. It returns the same job data that powers the Himalayas job board, including job titles, company details, salary ranges, location restrictions, timezone restrictions, categories, and application links.
If you are looking for an XML feed instead, see the Remote Jobs RSS Feed. For AI assistant integration, see the Remote Jobs MCP Server.
What endpoints does the API provide?
The API currently provides two endpoints:
https://himalayas.app/jobs/api https://himalayas.app/jobs/api/search
Use /jobs/api for the full unfiltered jobs feed and /jobs/api/search for filtered search results.
Browse all jobs with pagination
Use the browse endpoint when you want the full remote jobs feed:
https://himalayas.app/jobs/api
The browse endpoint accepts these optional query parameters:
- cursor: An opaque pointer to your position in the feed. Take the
nextCursorvalue from a response and pass it back to get the following page. This is the preferred way to paginate. - limit: The maximum number of jobs to return per request. Defaults to
20. Maximum value is20. - offset: The number of jobs to skip before returning results. Deprecated. Still supported, but it will be removed in a future release. Use
cursorinstead. Defaults to0.
Example request for the second page of results:
https://himalayas.app/jobs/api?limit=20&cursor=MjAyNi0wOC0yMVQwODozODoxNC4xNzc1NTBafDIwNjc2OTc
Do not build or parse cursor values yourself. The format is opaque and may change; treat a cursor as a token you echo back.
If you want to query by keyword, country, worldwide availability, seniority, employment type, company slug, timezone, sort order, or page, use the search endpoint section below.
Search jobs with filters
Use the search endpoint when you want filtered job results:
https://himalayas.app/jobs/api/search
The search endpoint currently accepts these query parameters:
- q: Free-text query
- country: Country filter
- worldwide: Worldwide-only filter
- exclude_worldwide: Exclude worldwide matches when country is present
- seniority: One or more seniority values
- employment_type: One or more employment type values
- company: One or more company slugs
- timezone: Timezone filter
- sort: Sort order
- page: 1-based results page
Search API examples:
https://himalayas.app/jobs/api/search?q=react%20engineer https://himalayas.app/jobs/api/search?country=US&seniority=Senior&sort=recent https://himalayas.app/jobs/api/search?company=linear&employment_type=Full%20Time https://himalayas.app/jobs/api/search?q=python&sort=salaryDesc&page=2
What does the API response look like?
The API returns a JSON object with the following top-level fields:
- updatedAt: ISO 8601 timestamp of when the data was last refreshed
- nextCursor: Pass this back as
?cursor=to fetch the next page. Omitted once there are no further pages. Its absence is how you know the walk is finished. - offset: The offset used in this request. Always
0on a cursor request, since offset played no part in selecting the page (deprecated, prefercursor) - limit: The limit used in this request
- totalCount: The total number of remote jobs available
- jobs: An array of job objects
What fields does each job include?
Each job object in the jobs array includes the following fields:
- title: Job title (e.g., "Senior Software Engineer")
- excerpt: Short plain-text summary of the job
- companyName: Name of the hiring company
- companySlug: Canonical company slug for filtering and stable lookups (e.g., "stripe")
- companyLogo: URL of the company logo image
- employmentType: Full-time, part-time, contract, etc.
- minSalary: Minimum salary in the stated pay period (number, or null if not provided)
- maxSalary: Maximum salary in the stated pay period (number, or null if not provided)
- salaryPeriod: Pay period for salary fields —
hourly,weekly,fortnightly,monthly, orannual(default) - seniority: Experience level (e.g., "Senior", "Mid", "Junior")
- currency: Salary currency code (e.g., "USD", "EUR")
- locationRestrictions: Array of countries where applicants must be based (empty array means worldwide)
- timezoneRestrictions: Array of accepted timezone offsets (empty array means all timezones)
- categories: Array of job categories (e.g., "Engineering", "Design")
- parentCategories: Array of parent category groupings
- description: Full job description as sanitized HTML
- pubDate: Publication date as an ISO 8601 string
- expiryDate: Expiration date as an ISO 8601 string
- applicationLink: URL to the job's application page on Himalayas
- guid: Unique identifier for the job listing
How do I paginate through all jobs?
Use cursor. Make a first request without one, then pass the nextCursor from each response back as ?cursor= on the next request. When a response has no nextCursor, you have reached the end of the feed.
- First request:
?limit=20 - Response contains
"nextCursor": "MjAyNi0wOC0yMVQ..." - Second request:
?limit=20&cursor=MjAyNi0wOC0yMVQ... - Repeat until a response has no
nextCursorfield
Cursor pagination is both faster and more reliable than offset. It stays fast no matter how deep into the feed you are, whereas offset requests get slower the further you go.
It is also more accurate. The feed is ordered by most recently updated, so positions shift while you are paging. With offset, that means a job can be returned twice or missed entirely. A cursor pins your exact position, so a cursor walk will never return the same job twice.
One thing a cursor cannot protect you from: a job that is updated while you are walking moves to the front of the feed, ahead of your position, so it will not appear in your remaining pages. If you are building a complete mirror of the feed, re-run the walk from the start periodically to pick those up.
Paginating with offset (deprecated)
offset still works, and existing integrations will keep functioning, but it will be removed in a future release. If you are still using it, start with offset=0 and increment by limit on each request, continuing until offset exceeds totalCount. We recommend migrating to cursor when convenient.
What is the rate limit?
The API is rate limited. If you exceed the rate limit, you will receive a 429 Too Many Requests response. The data is cached and refreshed every 24 hours, so there is no benefit to polling more frequently than once per day.
If you need a higher rate limit for a specific use case, contact the team at hi@himalayas.app.
How often is the data updated?
The API data is cached and refreshed every 24 hours. New job postings, expirations, and updates are reflected in the API within this window. For real-time results, use the Himalayas MCP Server which queries live data.
What is the difference between the Remote Jobs API, RSS feed, and MCP server?
Himalayas offers several ways to access job data programmatically:
- Browse API (
/jobs/api): The full jobs feed with cursor pagination. Up to 20 jobs per request. Best for building apps, databases, or dashboards. Updated every 24 hours. - Search API (
/jobs/api/search): Filtered job results by keyword, country, seniority, employment type, company, timezone, and more. Returns the same job shape as the browse API. Best when you need targeted results without crawling the full feed. - RSS Feed: The 100 most recent jobs in XML/Atom format. Best for feed readers and content aggregators. No pagination. Updated every 24 hours.
- MCP Server: Real-time job search, salary benchmarks, company research, and application tracking via AI assistants like Claude, Cursor, and Windsurf. Best for conversational job search and AI agent integrations.
For the RSS feed, see Remote Jobs RSS Feed. For MCP, see Remote Jobs MCP Server.
What are the attribution requirements?
If you display Himalayas job data on your own website or application, include a visible link back to himalayas.app and mention that the data is sourced from Himalayas. This helps support the platform and ensures users can find the original listings.
Is there an OpenAPI specification?
Yes. The Himalayas Jobs API is described by an OpenAPI 3.1 specification:
https://himalayas.app/docs/openapi.json
The spec includes the full request and response schema, all query parameters with types and constraints, enum values for fields like employmentType and currency, and error response definitions. Use it to auto-generate client libraries or validate responses.
How do I fetch jobs with Python?
import requests
response = requests.get(
"https://himalayas.app/jobs/api",
params={"limit": 20}
)
data = response.json()
print(f"Total jobs: {data['totalCount']}")
for job in data["jobs"]:
salary = ""
if job["minSalary"] and job["maxSalary"]:
salary = f" ({job['currency']} {job['minSalary']:,}–{job['maxSalary']:,})"
print(f"{job['title']} at {job['companyName']}{salary}")
To paginate through all jobs:
import requests
cursor = None
all_jobs = []
while True:
params = {"limit": 20}
if cursor:
params["cursor"] = cursor
data = requests.get("https://himalayas.app/jobs/api", params=params).json()
all_jobs.extend(data["jobs"])
cursor = data.get("nextCursor")
if not cursor:
break
print(f"Fetched {len(all_jobs)} jobs")
How do I fetch jobs with Node.js?
const response = await fetch("https://himalayas.app/jobs/api?limit=20");
const data = await response.json();
console.log(`Total jobs: ${data.totalCount}`);
data.jobs.forEach((job) => {
console.log(`${job.title} at ${job.companyName}`);
});
To paginate through all jobs:
let cursor = null;
const allJobs = [];
do {
const url = new URL("https://himalayas.app/jobs/api");
url.searchParams.set("limit", "20");
if (cursor) url.searchParams.set("cursor", cursor);
const data = await (await fetch(url)).json();
allJobs.push(...data.jobs);
cursor = data.nextCursor;
} while (cursor);
console.log(`Fetched ${allJobs.length} jobs`);
What does the full response schema look like?
{
"comments": "string - API release notes",
"updatedAt": "number - Unix timestamp (ms)",
"nextCursor": "string - pass back as ?cursor= for the next page. Omitted on the last page",
"offset": "number - offset used (deprecated, prefer cursor)",
"limit": "number - limit used",
"totalCount": "number - total jobs available",
"jobs": [
{
"title": "string",
"excerpt": "string",
"companyName": "string",
"companySlug": "string",
"companyLogo": "string (URL)",
"employmentType": "string (enum: Full Time | Part Time | Contractor | Temporary | Intern | Volunteer | Other)",
"minSalary": "number | null",
"maxSalary": "number | null",
"seniority": ["string (enum: Entry-level | Mid-level | Senior | Manager | Director | Executive)"],
"currency": "string (ISO 4217)",
"locationRestrictions": [{ "alpha2": "string", "name": "string", "slug": "string" }],
"timezoneRestrictions": ["string (UTC offset)"],
"categories": ["string"],
"parentCategories": ["string"],
"description": "string (sanitized HTML)",
"pubDate": "number (Unix timestamp ms)",
"expiryDate": "number (Unix timestamp ms)",
"applicationLink": "string (URL)",
"guid": "string"
}
]
}
For valid enum values and detailed field descriptions, see the Data Dictionary.
What error responses does the API return?
| Status | Meaning | When |
|---|---|---|
| 200 | Success | Valid request with results |
| 400 | Bad Request | Invalid query parameters, such as a non-numeric offset or a cursor that was not returned as a nextCursor |
| 429 | Too Many Requests | Rate limit exceeded |
When rate limited, wait and retry. The data refreshes every 24 hours, so there is no benefit to polling more frequently.
Where can I get help?
For API questions, higher rate limits, or integration support, email the team at hi@himalayas.app.
For AI agent integration guides, see the AI Agents hub. For field definitions and valid values, see the Data Dictionary. For general documentation, see How Remote Jobs Work on Himalayas.