Career Sites Jobs API πŸ’Ž avatar

Career Sites Jobs API πŸ’Ž

Pricing

from $2.70 / 1,000 job results

Go to Apify Store
Career Sites Jobs API πŸ’Ž

Career Sites Jobs API πŸ’Ž

GET low-cost premium access to 2M+ /jobs from 120,000+ career sites & 59 ATS platforms. Real-time stream of new jobs.

Pricing

from $2.70 / 1,000 job results

Rating

0.0

(0)

Developer

Luka

Luka

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Categories

Share

Jobs API πŸ’Ž

GET low-cost premium access to 2M /jobs from 120,000+ career sites & ATS. Ongoing real-time stream of new jobs.

2,000,000+ jobs. 59 ATS platforms. One endpoint.

The Jobs API gives you a read window into a single PostgreSQL table of jobs that we scrape continuously from 59 ATS platforms β€” Greenhouse, Workday, Lever, Ashby, SmartRecruiters, iCIMS, Personio, Rippling, BambooHR, Workable, Breezy, Recruitee, Teamtailor, Jobvite, Zoho, Paylocity, Paycom, Ultipro, OracleCloud, Taleo, and the rest. Every posting is parsed, normalized, scored, deduplicated, and indexed.

You get GET /api/jobs. That's the API.


The endpoint

GET /api/jobs?is_remote=true&country=United%20States&job_score_order=desc&limit=50

Response:

{
"backend": "postgresql",
"total": 12480,
"jobs": [
{
"id": "4819237401",
"slug": "4819237401",
"firestore_id": "4819237401",
"job_id": "4819237401",
"source_id": "greenhouse:4819237401",
"title": "Senior Content Writer",
"company_name": "Acme Co",
"company_type": "startup",
"company_logo_url": "https://logo.clearbit.com/acme.com",
"job_type": "writer",
"job_family": "Writing",
"subcategory": "Content Writing",
"workplace_type": "remote",
"employment_type": "FULL_TIME",
"experience_level": "senior",
"is_remote": true,
"location": "Austin, Texas, United States",
"city": "Austin",
"state": "Texas",
"country": "United States",
"location_country": "United States",
"salary": "120000-160000",
"compensation": {
"currency": "USD",
"min": 120000,
"max": 160000,
"period": "year"
},
"description": "Acme Co is hiring a Senior Content Writer to lead long-form content across our blog, docs, and customer education surfaces. You'll partner with product marketing, SEO, and design to ship 4-6 pieces a month that move pipeline and onboard users.",
"description_html": "<p>Acme Co is hiring a <strong>Senior Content Writer</strong> to lead long-form content…</p>",
"responsibilities": [
"Own the editorial calendar across blog, docs, and lifecycle emails",
"Write 4-6 long-form pieces per month tied to pipeline and activation goals",
"Partner with SEO on keyword strategy and on-page optimization",
"Interview subject-matter experts and translate technical concepts for a developer audience",
"Maintain a consistent voice across surfaces, with documentation and tooling to match"
],
"requirements": [
"5+ years writing for B2B SaaS or technical audiences",
"Portfolio of long-form published work with measurable outcomes",
"Comfort working with SEO tooling (Ahrefs, Clearscope, or similar)",
"Experience interviewing engineers and translating dense technical material",
"Native-level written English"
],
"benefits": [
"Fully remote across the US and EU",
"Equity in a profitable, growing company",
"Unlimited PTO with a 3-week minimum",
"Health, dental, vision (US) / private health stipend (EU)",
"$2,000/year learning budget",
"Home office stipend",
"Quarterly company offsite"
],
"hard_skills": ["SEO", "Content Strategy", "Editorial Planning", "CMS"],
"soft_skills": ["Cross-functional Collaboration", "Ownership"],
"tools": ["Ahrefs", "Clearscope", "Webflow", "Notion"],
"apply_url": "https://acme.com/careers/4819237401",
"job_score": 87,
"job_score_breakdown": {
"compensation": 90,
"remote": 100,
"freshness": 95,
"company": 70,
"completeness": 80
},
"source": "greenhouse",
"date_posted": "2026-07-22T15:04:11Z",
"created_at": "2026-07-22T16:11:09Z",
"image_data": {
"imageFile": "https://jobs.example.com/api/jobs/4819237401/image",
"imageUrl": "https://jobs.example.com/screenshot/4819237401",
"screenshotReadyAt": "2026-07-22T16:14:02Z"
}
}
],
"limit": 50,
"offset": 0,
"filters": {
"is_remote": "true",
"country": "United States",
"job_score_order": "desc",
"limit": "50",
"offset": "0"
}
}

Response envelope:

FieldMeaning
backendThe data backend ("postgresql")
totalTotal rows matching the filters, before limit/offset
jobsArray of job rows
limit / offsetEcho of your pagination
filtersEcho of every filter you sent (snake_case, canonical)

Every response is Cache-Control: no-store, no-cache, must-revalidate β€” what you get is what's in the database right now. CORS is wide open (Access-Control-Allow-Origin: *).


Query parameters

ParamTypeDefaultWhat it does
titlestringβ€”Case-insensitive substring (ILIKE %…%). title=writer matches "Senior Content Writer".
countrystringβ€”Exact match on location_country. United States, Germany, …
is_remotetrue / false / 1 / 0β€”Both spellings work
workplace_typestringβ€”remote, hybrid, on_site
employment_typestringβ€”FULL_TIME, PART_TIME, CONTRACTOR
experience_levelstringβ€”entry, mid, senior
job_familystringβ€”Coarse grouping (Writing, Engineering, …)
company_typestringβ€”startup, enterprise, agency
sourcestringβ€”Which ATS the row came from β€” greenhouse, workday, lever, …
date_posted_fromISO timestampβ€”date_posted >= value
date_posted_toISO timestampβ€”date_posted <= value
job_score_orderasc / descβ€”Sort by quality score. Without it, you get created_at DESC, date_posted DESC (freshest first)
limitint (1–100)50Hard cap at 100 per page
offsetint (0–1,000,000)0Standard pagination

Snake_case is canonical. CamelCase aliases (workplaceType, datePostedFrom, isRemote, …) work too.

Pagination walk

# Page 1
curl 'https://jobs.example.com/api/jobs?limit=100&offset=0'
# Page 2
curl 'https://jobs.example.com/api/jobs?limit=100&offset=100'
# …keep going while jobs.length == limit, or while offset < total

Filter combinations that work well

# High-quality remote jobs posted this week, US
/api/jobs?is_remote=true&country=United%20States&date_posted_from=2026-07-18&job_score_order=desc
# Senior engineering roles in Germany
/api/jobs?experience_level=senior&job_family=Engineering&country=Germany
# All Greenhouse postings mentioning "kubernetes" in the title
/api/jobs?source=greenhouse&title=kubernetes
# Hybrid contractor roles at startups
/api/jobs?workplace_type=hybrid&employment_type=CONTRACTOR&company_type=startup

The 59 ATS platforms

Every row in the table came from one of these. Each one has its own quirks β€” Greenhouse returns public job boards, Workday hides behind wd1/wd5 subdomains, Lever needs company slugs, Ashby uses posting-api/job-board/{clientname}, SmartRecruiters uses jobs-v2, iCIMS returns XML unless you pass content=false, Personio paginates with offset/limit, BambooHR needs an auth token, Rippling uses ats-api. The scraping pipeline handles all of that and normalizes the output into one schema, so you don't have to know which is which.

greenhouse, workday, lever, ashby, smartrecruiters, icims, personio, recruitee, teamtailor, workable, breezy, bamboohr, jobvite, rippling, zoho, workstream, oraclecloud, paylocity, paycom, ultipro, eightfold, comeet, gem, pinpoint, polymer, trakstar, dayforce, successfactors, taleo, hibob, adp-workforce-now, adp-myjobs, gohire, hireology, hirehive, hiringthing, jobscore, joincom, loxo, manatal, pageup, pyjamahr, recooty, applicantpro, avahr, freshteam, homerun, applytojob, easy.jobs, dover, recruitpro, catsone, candidatemanager, brassring, careerplug, careerpuck, applicantstack, apploi, harri, isolved

Every row carries its source in the source column. Filter by it to slice. Ignore it otherwise.


The job_family values

The job_family column is a closed enumeration. Use any of these values with the job_family filter β€” they're the canonical taxonomy the dataset is bucketed into.

Administration, Agriculture, Aviation & Maritime, Customer, Customer Support, Data, Design, Development, Education, Engineering, Finance, Government, Healthcare, Hospitality, Legal, Manufacturing, Marketing, Media & Entertainment, Mining & Resources, Operations, People, Personal Services, Product, QA & Testing, Real Estate, Research, Retail, Sales, Science & Research, Security, Skilled Trades, Sports, Veterinary, Writing

That's 34 canonical values. A handful of legacy rows still carry the older Qa spelling (a duplicate of QA & Testing) β€” treat them as the same. Older rows where the family hasn't been assigned yet have job_family = "unspecified".

Under each family you'll find subcategory values β€” those are open-ended. Writing has Content Writing, Copywriting, Technical Writing, Editing, Journalism, Translation. Development has Frontend, Backend, Full Stack, Mobile, DevOps, ML Engineering, Security Engineering, and so on. Filter by subcategory when you need that level of granularity.


What a job row looks like

The fields you'll actually use:

FieldTypeWhat it is
id / slugtextDeterministic 10-digit numeric id, same in both
firestore_idtextLegacy doc id (older rows)
job_id / source_idtextSource-system ids
titletextJob title
company_nametextHiring company
company_typetextstartup, enterprise, agency
job_typetextNormalized bucket (writer, engineer, …)
job_familytextCoarse grouping β€” one of the filter facets
subcategorytextFiner grouping under job_family
workplace_typetextremote, hybrid, on_site
employment_typetextFULL_TIME, PART_TIME, CONTRACTOR
experience_leveltextentry, mid, senior
is_remoteboolIndexed boolean β€” the hot filter
locationtextRaw location string as posted
city / state / countrytextParsed components
location_countrytextCanonical country used by the country filter
date_postedtimestamptzWhen the source listed it
created_attimestamptzWhen the pipeline wrote the row
salarytextRaw salary line
compensationjsonbParsed {currency, min, max, period} when extractable
job_scorenumeric0–100 quality score
apply_urltextApply link
description / description_htmltextRaw + sanitized
responsibilities / requirementstextExtracted bullets (newer rows)
hard_skills / soft_skills / toolsarrayExtracted skill tags
sourcetextWhich ATS β€” greenhouse, workday, …
image_datajsonbRendered preview {imageFile, imageUrl, screenshotReadyAt}

Indexes built for the queries that matter: (is_remote, created_at DESC), (is_remote, job_family, created_at DESC), (is_remote, location_country, created_at DESC), (is_remote, company_type, created_at DESC), (is_remote, date_posted DESC, created_at DESC), plus a GIN trigram on title. Substring search and common filter combinations stay fast as the table grows past 2M.


What you can build

A search widget on your site. Drop a country dropdown, a remote-only toggle, a job-family picker β€” every common filter maps to a query param. fetch('/api/jobs?…') and render the results. 100-row page size, paginate with offset.

A Slack or Telegram "new jobs" bot. Every hour, hit /api/jobs?date_posted_from=<one hour ago>&job_score_order=desc&limit=10. Post the top 10 to your channel. The filter does the work.

A daily email digest. Cron at 8am. date_posted_from=<yesterday>, sort by job_score_order=desc, group by job_family, render to email. Each link goes to apply_url.

A salary tracker. Pull all rows where compensation IS NOT NULL, group by location_country and job_family, average compensation.min and compensation.max. One query, structured data.

A recruiting funnel for outbound. Pull candidates with job_score_order=desc&limit=100, filter by experience_level and company_type to match your ICP, hit apply_url directly. The score sort means the top of the list is the highest-signal postings.

A vertical job board. If you're building for designers, marketers, engineers, devs, writers β€” filter by subcategory and you have a curated vertical feed. Add a sign-up gate, monetize the apply click.

A talent-marketplace watchlist. Save a query (is_remote=true&job_family=Engineering&country=Germany&title=staff). Hit it daily, diff against yesterday, alert your users when a match lands.

ATS migration. If you're building a job-board product, you don't need to engineer 59 scrapers yourself. Pull from this endpoint and ship your product. We already maintain the parsers, the proxies, the rate-limit handling, the de-duplication, the scoring.


For Excel File Exports

Visit jobstore.co for continous export of jobs in Excel file. Same data, same filters, build your file, and export.

Why? Community owners, online coaches, conference organizers, share jobs files with ther members. This solution makes the job sharing super simple.


What you're getting

  • 2,000,000+ rows, growing continuously
  • 59 ATS platforms normalized into one schema
  • Query latency dominated by the index β€” most filter combinations return in tens of milliseconds
  • CORS on, no auth on read, no rate limits on the read endpoint
  • no-store cache header, so polling is safe

One endpoint, one table, every job across 59 ATS platforms.