Looking for the overview — what this API returns, what it costs, and a call you can run without a key? See the Company Job Boards API page →
Jobs & Hiring

Company Job Boards API & Scraper

The ATS Job Boards API returns company-direct job postings pulled straight from applicant-tracking systems (Greenhouse, Lever and more) as clean JSON.

4 actionsLive JSON1,000 free credits$0.67–$1.50 / 1,000 creditsMCP-ready
Get a free keyOpen in playground

🤖 Using an AI assistant? Copy this link into ChatGPT / Claude / Cursor — it reads every endpoint and parameter instantly and tells you if this API fits your use case.

The primary company_jobs endpoint returns a company's open roles with title, URL, location(s), department and the ATS source — the authoritative postings, before they are syndicated to job boards. You can also fetch a single job_detail, search across companies and list the supported providers. It is built for recruiting tools, labor-market analysts and sales-intelligence teams that want first-source hiring data without scraping dozens of separate career pages. One ReefAPI key, one shared credit pool, the standard envelope.

Reference

The four providers, what to pass as company, and what each id looks like

The providers action returns exactly four keys and they do not behave the same way. Three of them serve one company's board; the fourth is a cross-company index and is the only one the search action accepts. Job ids are shaped differently per provider and mean nothing outside their own board. The table was measured on greenhouse/gitlab, lever/spotify, ashby/ramp and a workable search for 'python engineer'.

atsWhat to pass as companyjobs[].id shapeWhat we measured
greenhouseThe board token from the job-board URL, e.g. 'gitlab'10-digit numeric string: 8503792002, 8556658002company_jobs returned total 219. requisition_id is filled ('6263'); compensation was null.
leverThe org slug, e.g. 'spotify'Lowercase UUID: a0fa7da3-4c3c-4fa2-97bd-7d6eb01eb9e5total 90. employment_type 'full_time' and team ('Advertising R&D') filled; compensation null.
ashbyThe org slug, e.g. 'ramp'Lowercase UUID: 34413f8d-26bf-4bbc-8ade-eb309a0e2245total 134, and the only provider that returned pay: compensation{} plus salary{min:211400, max:290600, currency:'USD', source:'structured'}.
workableUse the search action rather than company_jobs22-character base62 code: oUJx9skkD6SnA9zEFabpodsearch 'python engineer' reported total 2226. company_jobs against Workable account slugs returned ok:true with total 0 in every test.
posted_date(all providers)ISO-8601, but the flavor differsGreenhouse carries a US-Eastern offset ('2026-04-17T05:58:03-04:00'), Lever and Ashby are UTC with sub-second precision, Workable ends in 'Z'. Normalize before sorting across boards.
count vs total(all providers)Two different numberscount is the rows in this response, total is the size of the whole board or result set. limit=3 on gitlab gave count 3 and total 219.
company echo(all providers)Not always what you passedGreenhouse echoes the board's display name ('GitLab'); Lever, Ashby and Workable echo the lowercase slug. company_slug always holds the slug.
bad valuesats / companyRejected differentlyAn ats outside the four is INVALID_PARAM with the allowed list attached. An unknown board token is NOT_FOUND. Passing 'greenhouse' to search is INVALID_PARAM, because only workable aggregates across companies.

Job ids do not collide across providers, and they are not portable either. A Lever UUID sent with ats=greenhouse returned NOT_FOUND, and a Greenhouse numeric id sent with ats=lever did the same. Keep the (ats, company, id) triple together as your key.

Live example

Real request and response JSON

Captured from the indexed primary action, search, on .

Captured request
{
  "method": "POST",
  "url": "https://api.reefapi.com/ats-jobs/v1/search",
  "headers": {
    "x-api-key": "$REEF_KEY",
    "content-type": "application/json"
  },
  "body": {
    "query": "python engineer",
    "ats": "workable"
  }
}
Captured response
{
  "ok": true,
  "meta": {
    "api": "ats-jobs",
    "endpoint": "search",
    "mode": "live",
    "latency_ms": 1742.1,
    "record_count": 50,
    "bytes": 418584,
    "cache_hit": false,
    "completeness_pct": 91.7,
    "ats": "workable",
    "total": 2059,
    "requests": 3,
    "charged_credits": 1,
    "version": "1.0.0"
  },
  "data": {
    "jobs": [
      {
        "id": "oUJx9skkD6SnA9zEFabpod",
        "title": "Senior Python Engineer",
        "url": "https://jobs.workable.com/view/oUJx9skkD6SnA9zEFabpod/remote-senior-python-engineer-in-argentina-at-binagora",
        "ats_source": "workable",
        "company": "Binagora",
        "location": "Argentina",
        "locations": [
          "TELECOMMUTE",
          "Argentina"
        ],
        "department": "004697001",
        "team": null,
        "employment_type": "contract",
        "remote": true,
        "workplace_type": "remote",
        "posted_date": "2026-09-18T14:05:39.152Z",
        "updated_date": "2026-09-18T14:05:39.152Z",
        "requisition_id": null,
        "apply_url": null,
        "compensation": null,
        "description_html": "<p><strong>About Binagora</strong></p><p></p><p>At Binagora, we are a fully remote community of software crafters with over a decade of experience partnering with international clients. We collaborate with bold organizations to deliver high-quality, custom solutions that achieve tangible results. Our expertise spans various sectors, including Media &amp; Entertainment, Solar Energy, Healthcare, Marketing, Audit &amp; Compliance, Diversity &amp; Inclusion, among many others. From initial strategy to final delivery, we go above and beyond, infusing creativity and aligning with business objective",
        "description_text": "About Binagora\n\nAt Binagora, we are a fully remote community of software crafters with over a decade of experience partnering with international clients. We collaborate with bold organizations to deliver high-quality, custom solutions that achieve tangible results. Our expertise spans various sectors, including Media & Entertainment, Solar Energy, Healthcare, Marketing, Audit & Compliance, Diversity & Inclusion, among many others. From initial strategy to final delivery, we go above and beyond, infusing creativity and aligning with business objectives to develop innovative products that challe",
        "company_slug": "binagora",
        "location_parsed": {
          "remote": false,
          "city": "Argentina"
        },
        "is_new": true,
        "is_active": true
      },
      {
        "id": "4BmmnW87oiMzKLBcbrqbbG",
        "title": "Senior Python Engineer",
        "url": "https://jobs.workable.com/view/4BmmnW87oiMzKLBcbrqbbG/senior-python-engineer-in-riga-at-aerones",
        "ats_source": "workable",
        "company": "Aerones",
        "location": "Riga, Riga, Latvia",
        "locations": [
          "Riga, Riga, Latvia"
        ],
        "department": "Research & Development",
        "team": null,
        "employment_type": "full_time",
        "remote": false,
        "workplace_type": "onsite",
        "posted_date": "2026-03-20T12:03:07.236Z",
        "updated_date": "2026-03-20T12:03:07.236Z",
        "requisition_id": null,
        "apply_url": null,
        "compensation": null,
        "description_html": "<p><strong>AERONES</strong>, the global leader in robotic wind turbine maintenance operating across 30+ countries, is seeking a <strong>Senior Python Engineer</strong> to build backend services and data pipelines using Django, PostgreSQL, and <strong>AI coding agents as your primary development tool</strong>.</p><p>This isn't traditional engineering where AI is optional — we're looking for engineers who've embraced autonomous AI coding agents (Claude Code, Cursor, Codex) as their core workflow, shipping production code through specification-driven, agent-augmented development.</p><p>Our softwa",
        "description_text": "AERONES, the global leader in robotic wind turbine maintenance operating across 30+ countries, is seeking a Senior Python Engineer to build backend services and data pipelines using Django, PostgreSQL, and AI coding agents as your primary development tool.\nThis isn't traditional engineering where AI is optional — we're looking for engineers who've embraced autonomous AI coding agents (Claude Code, Cursor, Codex) as their core workflow, shipping production code through specification-driven, agent-augmented development.\nOur software platform powers inspection analytics, operations planning, and ",
        "company_slug": "aerones",
        "location_parsed": {
          "remote": false,
          "city": "Riga",
          "region": "Latvia"
        },
        "is_new": false,
        "is_active": true
      },
      {
        "id": "vQLx5xU6w4HAbFusKAmTpL",
        "title": "Senior Python Engineer",
        "url": "https://jobs.workable.com/view/vQLx5xU6w4HAbFusKAmTpL/senior-python-engineer-in-london-at-man-group",
        "ats_source": "workable",
        "company": "Man Group",
        "location": "London, England, United Kingdom",
        "locations": [
          "London, England, United Kingdom"
        ],
        "department": null,
        "team": null,
        "employment_type": null,
        "remote": false,
        "workplace_type": "onsite",
        "posted_date": "2026-09-23T17:04:20.682Z",
        "updated_date": "2026-09-23T17:04:20.682Z",
        "requisition_id": null,
        "apply_url": null,
        "compensation": null,
        "description_html": "<p><strong>About Man Group</strong></p> <p>Man Group is a global alternative investment management firm focused on pursuing outperformance for sophisticated clients via our Systematic, Discretionary and Solutions offerings. Powered by talent and advanced technology, our single and multi-manager investment strategies are underpinned by deep research and span public and private markets, across all major asset classes, with a significant focus on alternatives. Man Group takes a partnership approach to working with clients, establishing deep connections and creating tailored solutions to meet thei",
        "description_text": "About Man Group\n Man Group is a global alternative investment management firm focused on pursuing outperformance for sophisticated clients via our Systematic, Discretionary and Solutions offerings. Powered by talent and advanced technology, our single and multi-manager investment strategies are underpinned by deep research and span public and private markets, across all major asset classes, with a significant focus on alternatives. Man Group takes a partnership approach to working with clients, establishing deep connections and creating tailored solutions to meet their investment goals and tho",
        "company_slug": "man-group",
        "location_parsed": {
          "remote": false,
          "city": "London",
          "country": "United Kingdom",
          "region": "England"
        },
        "is_new": true,
        "is_active": true
      }
    ],
    "count": 50,
    "total": 2059,
    "query": "python engineer",
    "ats_source": "workable"
  }
}
Actions

What the Company Job Boards API does

ActionDescriptionConcrete use caseKey params
company_jobsall open jobs for a board → {jobs[]{id,title,url,company,location,locations,...}, count, total, company, ats_source}. `ats`=greenhouse|lever|ashby|workable + `company` (board token/subdomain).Recruiting teams call company_jobs to get all open jobs for a board → {jobs[]{id,title,url,company,location,locations,...}, count, tota….ats, company, limit, cursor, page
job_detailone fully-populated job (description + requirements/benefits) by `ats` + `company` + `job_id`.Labor-market analysts call job_detail to get one fully-populated job (description + requirements/benefits) by `ats` + `company` + `job_id`..ats, company, job_id
searchcross-company job search over the Workable aggregator (170K jobs) → jobs[]. `query` + (default `ats`=workable). Filter by `workplace` (remote/hybrid/on_site) and `location`, which the aggregator applies itself, and by `posted_within_days`, which it does not offer and we apply over the pages your budget allows. Cost is bounded by `max_pages` and the response reports `pages_read` and `budget_exhausted`, so a result cut short by the budget is never mistaken for one the source ran out of.Job boards call search to get cross-company job search over the Workable aggregator (170K jobs) → jobs[].query, ats, workplace, remote, location, ...
providersthe supported ATS providers + their capabilitiesSales intelligence teams call providers to get the supported ATS providers + their capabilities.none
Code samples

Call search from your stack

curl -X POST https://api.reefapi.com/ats-jobs/v1/search \
  -H "x-api-key: $REEF_KEY" \
  -H "content-type: application/json" \
  -d '{"query":"python engineer","ats":"workable"}'
MCP one-liner
Ask your MCP-connected assistant: call reefapi.ats-jobs.search with {"query":"python engineer","ats":"workable"}.
Use cases

Who uses this API and why

  • Sales-intelligence teams call company_jobs to detect hiring signals (a company opening 10 sales roles) from the source ATS.
  • Job boards run company_jobs across a company list to aggregate fresh, first-source postings.
  • Labor-market analysts use search to measure open-role volume by department and location over time.
FAQ

Questions developers ask before integrating

Which ATS providers are actually supported?

The providers action returns four keys, alphabetically: ashby, greenhouse, lever, workable. Anything else is rejected at the parameter level with INVALID_PARAM and the allowed list in error.detail.allowed, so a typo in the provider name never turns into a silently empty result.

Is a job id unique across providers?

No, and the shapes are different enough that you can usually tell them apart: Greenhouse ids are 10-digit numeric strings, Lever and Ashby both use lowercase UUIDs, Workable uses a 22-character base62 code. An id is only meaningful inside one board, which we confirmed both ways: a Lever UUID with ats=greenhouse and a Greenhouse id with ats=lever both returned NOT_FOUND. Store the (ats, company, id) triple as the key.

Which provider gives me salary data?

Ashby, in our measurements. A Ramp job came back with a compensation object holding tiers and components, plus a normalized salary{min:211400, max:290600, currency:'USD', source:'structured'}. compensation was null on every Greenhouse, Lever and Workable job we read, so if pay is the point of your query, start with Ashby boards.

Why does search reject ats=greenhouse?

Only Workable runs a public cross-company index, so search is a Workable-only action and ats defaults to 'workable'. Passing greenhouse, lever or ashby returns INVALID_PARAM with a message pointing you at company_jobs. To search across Greenhouse boards you have to enumerate the board tokens yourself and call company_jobs per company.

What is the difference between count and total?

count is how many rows are in this response, total is the size of the underlying set. Asking gitlab for 3 jobs returned count 3 and total 219; spotify reported total 90 and ramp 134. On search, total is the size of the query's result set, 2226 for 'python engineer'. Use total to decide whether to page, not to size your array.

A job says remote: true but location_parsed.remote is false. Which is right?

Both, because they answer different questions. The top-level remote flag reflects whether the posting offers a remote option at all, which is why a Ramp job listed in New York with 'Remote (US)' among its locations reads remote:true. location_parsed.remote reflects only the primary location string, so it stays false unless that string itself says remote. workplace_type ('remote', 'hybrid', 'onsite') is usually the field you actually want.

Can I list one company's jobs on Workable?

Not reliably today. company_jobs with ats=workable and account slugs taken straight from search results returned ok:true with total 0 and an empty jobs array, and job_detail for those same ids returned NOT_FOUND. Treat Workable as a search-only surface, and use company_jobs for greenhouse, lever and ashby, where we verified live boards of 219, 90 and 134 jobs.

What do is_new and requisition_id mean?

is_new was true on the Workable rows posted within the previous week and false on the older Greenhouse, Lever and Ashby postings we read, so it is a freshness hint rather than a state you can rely on. requisition_id is the employer's own internal number, and only Greenhouse supplied it ('6263'); it is null on the other three providers.

What is the Company Job Boards API?

Company Job Boards API is a ReefAPI endpoint group for jobs straight from company career pages. It returns live JSON through POST requests under /ats-jobs/v1.

Is the Company Job Boards API free to try?

Yes. ReefAPI starts with 1,000 free credits, no card required. Company Job Boards calls use the same shared credit balance as every other ReefAPI engine.

Do I need a Company Job Boards login or account?

No login to Company Job Boards is needed for the API response. You call ReefAPI with your x-api-key header, and the playground can run live examples before you create a production key.

How fresh is the Company Job Boards data?

The page example is captured from a live company_jobs call, and production requests fetch live data through ReefAPI rather than a static sample.

How many credits does the Company Job Boards API use?

Company Job Boards actions currently cost 1 credit per successful call. Failed or blocked calls are free. All APIs draw from one credit pool.

Can I call Company Job Boards from an AI assistant or MCP client?

Yes. Connect ReefAPI once through MCP and your assistant can call ats-jobs actions with the same key, credit pool and JSON envelope used by normal REST requests.

docs / ats-jobs

Company Job Boards

Jobs straight from company career pages.

base /ats-jobs/v14 endpoints
post/ats-jobs/v1/company_jobs1 credit

all open jobs for a board → {jobs[]{id,title,url,company,location,locations,...}, count, total, company, ats_source}. `ats`=greenhouse|lever|ashby|workable + `company` (board token/subdomain).

ParameterAllowed / rangeDescription
atsrequiredgreenhouse · lever · ashby · workableApplicant-tracking system / job-board provider.
companyrequired—Board token / subdomain / org slug (e.g. greenhouse 'gitlab', lever 'spotify', ashby 'ramp'). Identifies one company's board.
limitoptional1–2000Max jobs to return (1-2000). Omit/0 = provider default (all).
cursoroptional—Opaque pagination cursor from a previous response (provider-specific).
pageoptional1–Page number for providers that paginate by page (alternative to cursor).
Try in playground →
post/ats-jobs/v1/job_detail1 credit

one fully-populated job (description + requirements/benefits) by `ats` + `company` + `job_id`.

ParameterAllowed / rangeDescription
atsrequiredgreenhouse · lever · ashby · workableApplicant-tracking system / job-board provider.
companyrequired—Board token / subdomain / org slug (e.g. greenhouse 'gitlab', lever 'spotify', ashby 'ramp'). Identifies one company's board.
job_idrequired—The job's id within that ATS board (from a company_jobs result's jobs[].id). Ids are only valid while the posting is open, so an id from an old example may return NOT_FOUND once the role is filled. Call company_jobs for a current one.
Try in playground →
post/ats-jobs/v1/providers1 credit

the supported ATS providers + their capabilities

Try in playground →
Built for volume
5M+ requests a day

Measured at 60 requests a second across the fleet, with no central bottleneck. Volume pricing is on request, and per-key limits are raised for high-volume accounts.

Missing a source?
We build it

Tell us a site we do not cover yet and it becomes an engine. A customer asked for bestprice.gr on a Sunday and it was in the catalog the next day.

Support
2 minute median reply

Median time from a question in the live chat to the first answer, measured across every answered conversation. Setup help included, no support tier to buy.

One key, one balance
Every API included

No per-site plans and no separate subscriptions. One key and one credit pool across the whole catalog, so adding a source costs nothing up front.

Planning something large? Tell us the volume and the sources and we will come back with what it costs and what we would have to build.