We publish scrapers for specific data sources on Apify — company registries, hiring data, that kind of thing. For job postings, we built four separate actors: one each for Greenhouse, Lever, Ashby, and SmartRecruiters, the four ATS (applicant tracking system) platforms that cover most of tech hiring. Each one worked fine. Each one also had almost no users — 2 to 4 each, after months live.
Then we checked who actually leads that category. One seller, one actor, covering five platforms at once (Greenhouse, Lever, Ashby, SmartRecruiters, and Personio). 51 real users, 1,324 runs. A second competitor, covering three of the four platforms in one actor, has 31 users. We were competing against both of them with a quarter of their coverage, split four ways.
The reason is obvious in hindsight: nobody doing hiring-signal research cares which ATS a company happens to use. "Who's hiring for this role right now" is the actual question. Which platform serves that answer is an implementation detail we were making the buyer deal with — go find our Greenhouse actor, then separately go find our Lever actor, then do it twice more, then merge the results yourself. The category leader just answers the real question once.
Why one scraper for four platforms isn't just gluing four API calls together
It sounds simple until you've actually looked at what these platforms return. We wrote about this in detail in an earlier post, before merging anything: Greenhouse wraps its job list in {jobs: [...], meta: {total}}. Ashby wraps it in {jobs: [...], apiVersion}. SmartRecruiters uses a real pagination envelope (offset/limit/totalFound). Lever is the only one that returns a bare array. None of the four use the same field names for the same concept — what's location.name in one is workplaceType plus a separate address object in another.
A one-platform scraper gets to ignore all of that. A real multi-platform actor has to normalize every incoming record to one consistent shape and keep a platform tag on each result, so a buyer running a query across companies on different ATS platforms gets one dataset back, not four shapes stitched together with duct tape. That reconciliation layer is the actual product. The API calls were always the easy part.
The second pattern: fan-out instead of union
Job postings merge by combining results — pull from every platform, union the lists, tag by source. We also just shipped a company-registry actor that merges six sources a different way: search for a company name, and it fans the same query out to five European business registries plus the global LEI (Legal Entity Identifier) database in parallel, since a given company only exists in one country's registry, not all of them. Same idea — one actor, multiple sources, no buyer-side orchestration — but the merge logic is structurally different: union when sources are complementary and should be combined, fan-out when sources are mutually exclusive and you're searching all of them to find the one that matches.
If you're building something that wraps more than one API behind a single interface, that's the actual design decision to make early: are your sources additive, or are they alternatives? We built both shapes as a result of getting this wrong once already — four actors doing a fan-out-shaped job where the market was already telling us, with real usage data, that union was the shape buyers wanted.
Where it stands now
Both merged actors are live — the old single-platform versions are retired in favor of them:
- Jobs Scraper — Greenhouse, Lever, Ashby & SmartRecruiters
- Company Registry Search — Europe + Global LEI (GLEIF)
It's early — these just replaced four actors with multi-month histories, so there isn't a real usage trend yet worth claiming as proof of anything. The part we can say with confidence, because it's just arithmetic on public Store data: four actors splitting 2-4 users each was never going to out-compete one actor with 51. Fragmenting a market across near-identical tools doesn't create four audiences — it just makes each of the four harder to find than the one obvious choice would have been.
Top comments (0)