Building a job feed without scraping

Many hiring platforms publish public job board endpoints. How to build a job feed on them without proxies or HTML parsing, and where the approach breaks down.

Most people who want job data start by scraping. They write a crawler for LinkedIn or Indeed, it gets blocked, they buy proxies, and soon they are paying to keep up with countermeasures. There is a quieter route for a large share of employers. Their applicant tracking system already publishes the open roles as structured JSON on a public endpoint. You can read it with a plain HTTP request. No login, no browser automation, no rotating IP addresses.

This article explains how that works, what you get, how to run it responsibly and where it stops working. The last part matters most. A feed built this way is clean and cheap. It is also incomplete in ways that are easy to miss.

Why the endpoints exist

An applicant tracking system, or ATS, is the software a recruiting team uses to post roles and manage candidates. Companies want their open roles on their own careers page. The ATS vendor makes that easy by exposing the live list of published jobs through an API that a careers page can call directly. The vendor designed it to be read by anyone, because a careers page is public by definition.

That is the key difference from scraping. You are not pulling data out of HTML meant for human eyes. You are using an interface the vendor built for machines, for data the employer chose to publish. The response format stays stable because the vendor's own customers depend on it.

Several widely used platforms work this way.

Greenhouse offers a Job Board API. A GET request to a board URL that contains the company's board token returns its published jobs. An optional parameter adds the full description text.

Lever offers a Postings API. A request to a postings URL with the company's site name returns published postings as JSON.

Ashby offers a public job posting API for each hosted job board. It can optionally include compensation data where the employer has entered it.

SmartRecruiters and Workable also expose public listings for companies that use their hosted careers pages.

Each vendor documents these endpoints itself. Read that documentation before you build anything, because parameter names and response fields change between API versions.

What you actually get

A typical response gives you a job title, a location string, a department or team, a posting URL, a job identifier and some kind of timestamp. Depending on the vendor you may also get employment type, a workplace type field, a description in HTML and sometimes a salary range.

Three things make this data better than scraped data.

It is first party. The employer entered it into its own system. No aggregator rewrote the title or merged two roles into one.

It is complete for that employer. The endpoint returns every role the company has published on that board, not a ranked subset chosen by a search algorithm.

It has stable identifiers. The same job keeps the same ID across requests. That lets you detect when a role appears and when it disappears, and that is the basis of any hiring signal.

Finding the companies

The endpoints are public, but no official directory lists which companies use which ATS. This is the first real piece of work.

The usual approach is to start from a list of companies you care about and look at their careers pages. The link to an open role often reveals the platform and the company's board name in the URL. Once you have that name, you can call the endpoint directly from then on.

Keep the mapping in a table you maintain. Companies switch ATS vendors. They rename boards after a rebrand or an acquisition. A board that returns an empty list may mean the company has no open roles, or it may mean the company moved to another system. Your feed cannot tell those apart without a check. So record the date you last confirmed each mapping, and re-verify boards that go quiet.

Running it without proxies

Proxies are a tool for hiding who you are from a site that does not want you there. With public ATS endpoints you have nothing to hide. That changes how you should build the collector.

Identify yourself. Send a descriptive User-Agent with a way to reach you. The SEC makes this an explicit requirement for automated access to EDGAR and publishes a request rate ceiling in its guidance on accessing EDGAR data. Most ATS vendors do not publish rules that clear. The SEC's approach is still a sensible default. Say who you are and keep your request rate modest.

Poll gently. Job boards do not change by the second. One request per company per day is enough for most uses. If you need faster detection of new roles, a few times a day is still far below anything a careers page sees from real visitors.

Spread requests out. Do not fire a thousand requests to one vendor in the same second because your cron job starts at midnight. Add a delay between calls and stagger the schedule.

Handle errors quietly. A 404 usually means the board name is wrong or gone. A 429 means slow down. Back off, record it, and try again later. Do not retry in a tight loop.

Store raw responses. Keep the JSON you received with a timestamp before you transform it. When a vendor changes a field, you can reprocess history instead of losing it.

Read the terms. Public does not mean unrestricted. Check each vendor's API terms for limits on how the data may be used or redistributed, especially if you plan to sell a derived product.

Turning snapshots into a feed

A single request gives you a snapshot. A feed comes from comparing snapshots over time.

Diff by job ID. A new ID is a new posting. A missing ID is a closed or unpublished posting. A changed title or location on the same ID is an edit, not a new role.

Treat timestamps with care. Some vendors expose a creation date. Others expose only an updated date, which moves whenever a recruiter edits the text. If you use updated dates as posting dates, old roles will look new. When the vendor gives you nothing reliable, use the first date your own collector saw the ID. Label it that way.

Deduplicate across locations. Employers often post the same role once per city. Five IDs may describe one hiring decision. Decide whether you count postings or roles, and say which one you publish.

Normalize fields last. Location strings, department names and workplace flags vary widely. Remote flags in particular reflect what the employer typed into a form, not a verified fact. Keep the original value next to your normalized one so users can see what you changed.

Where the approach stops working

This is where honesty matters. A feed built on public ATS endpoints has hard limits.

Not every ATS publishes an open endpoint. Some large enterprise systems, Workday among them, power careers sites through interfaces that are not offered as public APIs. You can sometimes see JSON requests in the browser's network tab. Calling those undocumented interfaces is closer to scraping than to using a published API. It can break without notice and may conflict with the site's terms. If your company list leans toward large enterprises, expect a real share of them to fall outside a clean public feed.

Coverage follows vendor choice, not the economy. The platforms with open endpoints are popular with technology companies and venture-backed startups. Hospitals, retailers, manufacturers and government agencies often use other systems. A feed built this way over-represents some sectors. Aggregate trends from it describe your company sample, not the labor market.

A posting is not a hire. Companies leave evergreen roles open to collect applicants. They post roles they may never fill. They close postings when a hiring freeze starts, not when a hire is made. A rise in postings is a statement of intent at best.

Employers control the data. They can unpublish roles, reuse IDs after a migration or move roles to an internal board. You see what they choose to show on a given day.

Agencies and outsourced hiring are invisible. If a company hires through recruiters or staffing firms, its own board may understate its demand.

Some sites will block you anyway. Vendors can add rate limits or bot protection to any endpoint. If an endpoint starts demanding things a normal careers page would not, respect that. The whole point of this approach is that you do not need to fight anyone.

Free alternatives worth knowing

You do not always need to build this.

For the aggregate picture of US job openings, the Bureau of Labor Statistics publishes the Job Openings and Labor Turnover Survey. It is a survey with a known methodology, covers the whole economy and costs nothing. It will not tell you which company is hiring, but it gives you the baseline your company-level feed can never provide.

For federal government roles, USAJOBS offers an official developer API. You request a free key and query postings directly.

For a handful of companies, the ATS endpoints described above are free to call yourself. A short script and a spreadsheet of board names will get you far.

Paid feeds make sense once you need thousands of companies, maintained mappings, history and normalization you do not want to run yourself. That is a build or buy decision about maintenance time, not about access to secret data.

Why hiring data pairs well with filings

Company-level hiring signals are most useful next to other public records. A private company that raises capital often starts hiring shortly after. The raise itself shows up in a Form D filing with the SEC, and our guide on how to read a Form D filing covers what those filings contain. When a new Form D and a jump in open roles appear at the same company, you have two independent public sources pointing the same way. Neither proves anything alone. Together they give you a better question to ask. None of this is investment advice.

If you want the capital side of that picture already collected and scored, our Startup Capital Raises Form D report tracks new private raises from SEC filings so you can match them against the hiring activity you see in your own feed.


Want the signal instead of the raw filings? Get a free report preview. Prefer the tool to the write-up? Browse all data feeds or connect the free MCP server.