ats_fetch_board
Fetches live job postings directly from a company's ATS public API (Greenhouse, Lever, Ashby, Workday). Bypasses JavaScript-rendered career pages that appear empty, returning normalized JSON.
Instructions
Read one company's job board from its ATS's public API, normalized.
Use this instead of fetching a careers page: Greenhouse, Lever, and Ashby boards are JavaScript shells whose HTML contains no postings, so a page fetch returns an empty-looking board for a company that is actively hiring. This reads the same postings the board renders, as JSON.
platform is greenhouse, lever, ashby, or workday —
the four that publish a board API. iCIMS, SuccessFactors, and Taleo
publish none, so coverage of employers on those systems is deliberately
partial; cross-check them against an aggregator. slug is the bare
board slug, not a URL — the last path segment of the board address
(labelbox, people-ai, handshake) — except for workday,
whose identity has three parts: pass tenant.wdN/site
(adobe.wd5/external_experienced) or the board URL itself. Workday
reads are paged 20 at a time, so large tenants are slow when unfiltered
— pass a title_filter and it is pushed down as a Workday search,
which is cheap; Workday postings carry approximate day-resolution
posted dates and never compensation. Pass company with the
company you expect this slug to belong to and the result is checked
against the board's own name: mismatches come back as NAME_MISMATCH
with the jobs still attached, which is how you catch a slug that points
at a different company of the same name. Only Greenhouse publishes a
board name, so this check is inert for Lever and Ashby.
title_filter keeps postings whose title contains any of the given
strings (case-insensitive). updated_since is an ISO date that keeps
postings posted or updated at/after it. keywords is different from
both: it never drops a posting — every returned job gains a
keyword_hits list naming which of your keywords its title, team, or
description mentions. Use it for ranking signal in high-volume searches
(e.g. a stack list like ["Salesforce", "HubSpot", "Clari"]); since
stacks are named in descriptions, pair it with include_descriptions
for meaningful hits. include_descriptions adds a
plain-text snippet per job (~1,500 chars) and makes the Greenhouse
request much larger, so it defaults off. full_descriptions goes one
step further and returns each posting's whole description, untruncated
(it implies include_descriptions): use it to go deep on one board
whose roles a sweep has already surfaced, paired with a title_filter
or a small limit so the read stays readable — long postings run to
several thousand characters each. Keyword hits are then found anywhere
in the posting, not only in its first 1,500 characters. The field is
still named description_snippet so pipelines see one shape.
limit/offset page through the matches, response_format is
markdown (a table, for reading) or json (for pipelines).
The result always reports total_on_board, matched (after your
filters), and count (this page), so a filtered or paginated read can
never be mistaken for the whole board. Board trouble is reported as a
status on the result — BOARD_EMPTY, SLUG_NOT_FOUND,
NOT_FOUND_OR_API_DISABLED, RATE_LIMITED, UPSTREAM_ERROR,
TIMEOUT — each with a detail saying what it means and what to do
next. An empty board is not a dead company, and a 404 is not proof of
one; read the detail before concluding anything. Compensation is
reported only where the platform publishes it as structured data, never
read out of the description text.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| slug | Yes | ||
| limit | No | ||
| offset | No | ||
| company | No | ||
| keywords | No | ||
| platform | Yes | ||
| title_filter | No | ||
| updated_since | No | ||
| response_format | No | markdown | |
| full_descriptions | No | ||
| include_compensation | No | ||
| include_descriptions | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |