

The dataset behind the Lazee job board, over REST. Open roles pulled straight from 87 company career sites on Greenhouse, Lever, Ashby, SmartRecruiters, Workday, BambooHR, ClanX, Y Combinator, Superteam and Google Careers, tagged by role, level, country and workplace so you can filter them in one request. Refreshed every 2 days.
The Jobs API will be served through a third-party API marketplace, not from lazee.dev. You will subscribe, get a key and be billed there. The marketplace, base URL, plans and rate limits are announced at launch. Everything else on this page, the endpoints, filters, response shapes and refresh cadence, is the contract we are building to.
Want early access or a field we don't list? Say so and we will reach out before launch.
One read-only REST API, JSON in and out, versioned under /v1. It returns the same rows the job board shows: every open role we found on the career sites we track, with the original posting URL. Nothing is user-submitted and nothing is scraped from aggregators; each job comes from the company's own board on its ATS.
url is the job page on the ATS itself. Every platform listed here is one the Lazee extension autofills.Not included: full job descriptions, salary normalisation, and jobs from boards we do not track yet. See the FAQ.
A scheduled sync runs every 2 days (about every 48 hours). It fetches every tracked board in full and brings the dataset in line with what the boards list at that moment:
first_seen_at set to the sync time.synced_at.synced_at tells you when a job last actually changed.What that means for your integration
meta.last_synced_at changes.posted_after with your last run's last_synced_at to pick up only what is new.posted_at is the board's own date when it publishes one. Boards that only show relative dates keep the first value we recorded.Every request carries an API key in a request header. Keys are issued by the marketplace when you subscribe, and the exact header name follows the marketplace's convention. The examples on this page use X-API-Key as a stand-in; swap it for the header shown on your subscription page.
GET https://<announced-at-launch>/v1/jobs?role=frontend
X-API-Key: YOUR_API_KEY
Accept: application/jsonKeys are for server-side use. Do not ship one inside a browser or mobile app; proxy the call through your own backend instead.
Base URL: https://<announced-at-launch>/v1 (placeholder until launch). All endpoints are GET and return application/json.
/jobsSearch and filter jobs. Paginated, newest first.
/jobs/{id}One job by id. 404 once its board takes it down.
/filtersEvery accepted value for role, level, region, workplace and platform, with labels, plus the list of companies.
/statsDataset size, number of companies and platforms, and the last sync time.
{
"data": {
"total_jobs": 1284,
"companies": 87,
"platforms": 10,
"last_synced_at": "2026-10-22T02:00:00.000Z",
"refresh_interval_hours": 48
}
}/jobsEvery parameter is optional and they combine with AND. A parameter that accepts several values matches any of them (OR within the parameter). Unknown parameters are ignored; known parameters with a bad value return 400.
| Parameter | Type | Description | Default |
|---|---|---|---|
q | string | Free-text search. Case-insensitive match against the job title, company name and location. | — |
role | enum | Role category worked out from the title. One of the role keys below, or engineering for every engineering role at once. Comma-separate several keys to match any of them. | — |
level | enum | Experience level. One or more level keys, comma-separated. | — |
region | enum | Country or region the job is in. A job with several offices matches every region it mentions. | — |
workplace | enum | remote, hybrid or onsite. Jobs whose board doesn't say have null and never match this filter. | — |
platform | enum | The ATS the job is hosted on. One or more platform keys, comma-separated. | — |
company | string | Exact company name, case-insensitive (for example Stripe). Comma-separate several. | — |
has_compensation | boolean | true returns only jobs whose posting lists a pay range. | false |
posted_after | date | ISO 8601 date or datetime. Only jobs with posted_at on or after this moment. | — |
sort | enum | posted_desc (newest first) or posted_asc. Ties are broken by id so pages never overlap. | posted_desc |
page | integer | 1-based page number. | 1 |
limit | integer | Results per page, 1 to 100. | 25 |
Response: an array under data plus a meta object.
{
"data": [ /* job objects, see "The job object" */ ],
"meta": {
"page": 1,
"limit": 25,
"total": 1284,
"total_pages": 52,
"last_synced_at": "2026-10-22T02:00:00.000Z"
}
}/jobs/{id}The same object appears in list results and from the single-job endpoint (wrapped in data). Field names are snake_case; timestamps are ISO 8601 in UTC.
{
"id": "cmh3k9x2a0001qzk8f1g7h4jd",
"platform": "GREENHOUSE",
"company": "Stripe",
"title": "Backend Engineer, Payments",
"location": "San Francisco, CA / Remote (US)",
"workplace": "remote",
"department": "Engineering",
"employment_type": "Full-time",
"compensation": "$180,000 – $250,000",
"url": "https://boards.greenhouse.io/stripe/jobs/1234567",
"posted_at": "2026-10-21T09:15:00.000Z",
"first_seen_at": "2026-10-22T02:00:00.000Z",
"synced_at": "2026-10-22T02:00:00.000Z",
"role": "backend",
"level": "mid",
"regions": ["us"]
}| Field | Type | Description |
|---|---|---|
id | string | Stable identifier for the job. Survives updates to the posting. |
platform | enum | ATS the job is hosted on. One of the platform keys below. |
company | string | Company name as the board publishes it. |
title | string | Job title as posted. |
location | string | null | Location text from the board, untouched. Can list several offices. |
workplace | enum | null | remote, hybrid, onsite, or nullwhen the board doesn't say. |
department | string | null | Board's own department or team label, when it has one. |
employment_type | string | null | Full-time, Contract, Internship and so on, as the board words it. |
compensation | string | null | Pay range exactly as the posting shows it. Not normalised to a currency or number. |
url | string | The job page on the ATS itself. Apply there; the Lazee extension autofills it. |
posted_at | datetime | The board's posted date. When a board has none, the moment we first saw the job. |
first_seen_at | datetime | When the job first appeared in a sync. |
synced_at | datetime | The last sync that added or changed this job. Unchanged jobs keep their earlier value. |
role | enum | null | Role key from the title and department. null for roles outside the list (finance, legal, recruiting). |
level | enum | Level key from the title. Titles with no level cue are classed mid. |
regions | string[] | Every region key the location mentions. Empty when none is recognised. |
/filtersThese are the keys the filters accept today, generated from the same taxonomy the job board uses. Fetch /filters at runtime rather than hard-coding them; new keys may be added, existing ones are not renamed within /v1.
Plus engineering, a shortcut for every key in the Engineering group.
softwareSoftware engineeringfrontendFrontendbackendBackendfullstackFull stackmobileMobileai-mlAI / MLdataDatadevopsDevOps & infrastructuresecuritySecurityqaQA & testinghardwareHardware & embeddedproductProduct & programdesignDesignsalesSalesmarketingMarketing & growthsupportCustomer success & solutionsinternInternshipentryEntry levelmidMid levelseniorSeniorstaffStaff & principalmanagerManager & aboveusUnited StatesindiaIndiacanadaCanadaukUnited KingdomeuropeEuropesingaporeSingaporejapanJapanremoteRemotehybridHybridonsiteOn-siteGREENHOUSEGreenhouseLEVERLeverASHBYAshbySMARTRECRUITERSSmartRecruitersWORKDAYWorkdayBAMBOOHRBambooHR{
"data": {
"role": [{ "key": "backend", "label": "Backend" }, ...],
"level": [{ "key": "senior", "label": "Senior" }, ...],
"region": [{ "key": "india", "label": "India" }, ...],
"workplace": [{ "key": "remote", "label": "Remote" }, ...],
"platform": [{ "key": "GREENHOUSE", "label": "Greenhouse" }, ...],
"company": ["Airbnb", "Anthropic", "Stripe", ...]
}
}Results are paged with page and limit. The default page size is 25 and the maximum is 100. meta.total is the number of jobs matching your filters and meta.total_pages is the last page you can request; asking for a page past it returns an empty data array, not an error.
Ordering is by posted_at then id, so paging through a result set between two syncs is stable. A sync in the middle of a long crawl can shift rows; compare meta.last_synced_at across pages and restart if it changed.
Errors use standard HTTP status codes and a JSON body with a machine-readable code and a human message. Validation errors also name the offending param.
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"error": {
"code": "invalid_parameter",
"message": "level must be one of: intern, entry, mid, senior, staff, manager",
"param": "level"
}
}| Status | code | Meaning |
|---|---|---|
| 400 | invalid_parameter | A query parameter has a value outside its allowed set or format. The response names the parameter. |
| 401 | unauthorized | The API key is missing, malformed or revoked. |
| 404 | not_found | No job with that id. Jobs taken down by their board are deleted on the next sync and 404 afterwards. |
| 429 | rate_limited | Too many requests for your plan. Retry after the number of seconds in the Retry-After header. |
| 500 | internal_error | Something failed on our side. Safe to retry with backoff. |
Plans, quotas and prices are set on the marketplace and published at launch. Expect a free tier sized for prototyping and paid tiers by monthly request volume. Rate limits are enforced per key; a 429 carries a Retry-After header.
Because the data only changes every 2 days, most integrations need far fewer requests than they first assume. One full pull per sync, filtered to what you need, is usually enough.
Senior backend or full-stack roles, remote, in India:
curl "https://<announced-at-launch>/v1/jobs?role=backend,fullstack&level=senior®ion=india&workplace=remote&limit=10" \
-H "X-API-Key: YOUR_API_KEY"Engineering roles mentioning “payments”, posted this month, with a listed pay range:
const params = new URLSearchParams({
q: "payments",
role: "engineering",
has_compensation: "true",
posted_after: "2026-10-01",
limit: "50",
});
const res = await fetch(`https://<announced-at-launch>/v1/jobs?${params}`, {
headers: { "X-API-Key": process.env.LAZEE_JOBS_API_KEY },
});
if (!res.ok) throw new Error(`Jobs API ${res.status}`);
const { data: jobs, meta } = await res.json();
console.log(`${meta.total} jobs, refreshed ${meta.last_synced_at}`);
for (const job of jobs) console.log(job.company, "—", job.title, job.url);Entry-level and intern roles in the US on Ashby or Lever:
import os, requests
resp = requests.get(
"https://<announced-at-launch>/v1/jobs",
params={"platform": "ASHBY,LEVER", "level": "entry,intern", "region": "us", "page": 1},
headers={"X-API-Key": os.environ["LAZEE_JOBS_API_KEY"]},
timeout=15,
)
resp.raise_for_status()
body = resp.json()
for job in body["data"]:
print(job["company"], "-", job["title"], job["url"])
print("page", body["meta"]["page"], "of", body["meta"]["total_pages"])On a third-party API marketplace, not on lazee.dev. We have not picked the marketplace yet. This page is updated with the base URL, plans and a launch date as soon as that is settled.
Not at launch. Each job carries the URL of the original posting, where the description lives. Descriptions are the most requested addition, so tell us if you need them and how you would use them.
No. compensation is the text the board shows, which varies in currency, period and format. has_compensation=true narrows to jobs that list a range at all.
They are derived from the title, department and location with rules tuned on the boards we track, not read from a structured field, so a small share of jobs are tagged imperfectly. A title with no level cue is classed mid; a role we don't categorise (finance, legal, recruiting) has role: null.
Yes, if it is hosted on one of the supported platforms. Send the company's careers URL through the feedback form.
You can browse and filter the same dataset today on the job board. There is no programmatic access until the API launches; please do not scrape the board.
asiaaustraliaAustralia & NZlatamLatin Americamiddle-eastMiddle EastCLANXYCOMBINATORY CombinatorSUPERTEAMSuperteamGOOGLEGoogle Careers