Jobs
Company Tech Stack Scraper — BuiltWith Alternative
A free BuiltWith / Wappalyzer alternative for the back-end: detect a company's real tech stack (Postgres, Django, AWS, Kubernetes, Snowflake…) straight from its Greenhouse, Lever and Ashby job posts — pay-per-result, no SaaS subscription, no login.
Free Apify credit covers a first run. No credit card to try.
What this Actor scrapes
Three ATS platforms, one unified schema:
1. Greenhouse — boards-api.greenhouse.io/v1/boards/{token}/jobs?content=true 2. Lever — api.lever.co/v0/postings/{token} 3. Ashby — api.ashbyhq.com/posting-api/job-board/{token} (token is case-sensitive — Ramp, not ramp)
What we handle for you
- Three ATSs, one schema — Greenhouse, Lever, and Ashby normalised to an identical row shape.
- Curated tech vocabulary — ~110 canonical names spanning languages (Python, Go, Rust), frameworks (Django, React, FastAPI), databases (Postgres, MongoDB, Redis, Snowflake), cloud (AWS, GCP, Azure, Vercel), infra (Kubernetes, Terraform, Docker), CI/CD, observability, and ML/data tools.
- Per-company fault isolation — one bad token (404 from Lever, typo on Ashby) does not abort the run; the other companies still produce data.
- Pydantic v2 validation — every input and every output row is model-validated before landing in the dataset.
- Filter knobs —
maxJobsPerCompanycap andminTechsDetectedfloor let you drop generic non-engineering postings. - Exponential backoff — 408 / 429 / 503 retries with
Retry-Afterhonoured; up to 5 attempts per request. - Deterministic detection — regex + vocabulary, not LLM. High precision, zero hallucinated tools.
Use cases
- B2B sales qualification — enrich every Salesforce or HubSpot account with the company's live back-end stack: "they hire Django + Postgres + AWS" tells you whether to pitch your Postgres-tuning SaaS.
- Recruiter sourcing — pull every senior backend role from your target accounts and filter by
detected_techsto find teams that match your candidate's stack. - Competitive intelligence — track which competitors are hiring for
KubernetesorSnowflakeand infer their roadmap before it's announced. - CRM enrichment — replace TheirStack / BuiltWith / Wappalyzer subscriptions for the segment of buyers who publish their stack in job descriptions anyway.
- Investment research — map private-company tech footprint over time without a Crunchbase Pro seat.
- Open-source stack maps — feed a public page that ranks the most-hired-for technologies among YC-backed startups.
Input
Paste this into the Apify Console, or send it as the run input over the API. Proxy settings are on by default; you rarely need to touch them.
| Field | Type | Required | What it does |
|---|---|---|---|
companies | array | yes | List of {companyToken, atsType} pairs. atsType is one of greenhouse, lever, ashby. companyToken is the board slug in the ATS URL (e.g. airtable for Greenhouse, palantir for Lever, Ramp for Ashby — Ashby is… |
maxJobsPerCompany | integer | no | Hard cap on rows emitted per company. Leave empty for no cap. |
minTechsDetected | integer | no | Drop jobs whose detected_techs list has fewer than this many entries. 0 keeps every job. |
useProxy | boolean | no | Route requests via Apify Proxy (BUYPROXIES94952). All three ATS APIs are public — only enable if you observe rate-limiting. |
{
"companies": [
{
"companyToken": "airtable",
"atsType": "greenhouse"
},
{
"companyToken": "Ramp",
"atsType": "ashby"
}
],
"minTechsDetected": 0,
"useProxy": false
} Output
One row per result, schema-validated before it is written. Export JSON, CSV, Excel or XML from the run, or read it over the API.
atscompany_tokenjob_idtitlelocationdepartmenturldescription_textdetected_techsposted_atscraped_at
{
"ats": "greenhouse",
"company_token": "airtable",
"job_id": "4812345",
"title": "Senior Backend Engineer",
"location": "Remote",
"department": "Engineering",
"url": "https://boards.greenhouse.io/airtable/jobs/4812345",
"description_text": "We use Python, Django, PostgreSQL, and AWS...",
"detected_techs": [
"AWS",
"Django",
"Postgres",
"Python"
],
"posted_at": "2026-05-01T09:00:00Z",
"scraped_at": "2026-06-01T12:00:00Z"
} Pricing
| Event | Price | When |
|---|---|---|
| Actor start | $0.20 | Once per run, covers warm-up and proxy session setup. |
| Job result row | $0.0050 | Per result written to the dataset. |
You pay only for results that land. Cap any run with maxTotalChargeUsd. See pricing & billing for worked examples.
Limitations
- Tech detection is regex-based, not LLM-based — it is deterministic and high-precision, but will miss tools not in the curated ~110-name vocabulary. Submit a feedback request to add more terms.
- ~85% recall — job descriptions that omit or abbreviate tool names will not surface every dependency in a company's stack. This is an inherent limit of job-description parsing, not an Actor bug.
- Ashby tokens are case-sensitive —
Rampworks;rampreturns zero jobs. Double-check the exact token from the company's Ashby board URL. - Greenhouse double-encoding — Greenhouse wraps its
contentfield in double HTML-encoding (<div>for<div>). The parser unescapes twice before stripping tags; unusual encoding in edge-case boards may still slip through. - Lever
descriptionPlaingaps — Lever sometimes omits the "Requirements" bullet list fromdescriptionPlain. The parser concatenates everylists[].contentchunk to recover skills listed there; however, lists in non-standard formats may be missed. - Default dataset retention — Apify FREE-tier default storage retains datasets for 7 days. Use
Actor.open_dataset(name="…")or export immediately if you need to outlive that window. - No personal-data extraction — this Actor reads public job posts and company-aggregated tech signals only. It does not extract candidate data or applicant details from any ATS.
FAQ
Q: What makes this different from BuiltWith or Wappalyzer?
Q: Is scraping these ATS job boards allowed?
Q: How do I find the token for a company on Greenhouse / Lever / Ashby?
jobs.lever.co/{token}, boards.greenhouse.io/{token}, or jobs.ashbyhq.com/{Token}. Ashby tokens are case-sensitive — copy them exactly as they appear in the URL.Q: Can I scrape hundreds of companies in one run?
{companyToken, atsType} pairs as you need. One bad token (404 or empty board) does not abort the run — the others still produce data. Use maxJobsPerCompany to cap the volume and keep costs predictable.Q: What happens when a company rate-limits my requests?
Retry-After headers. If a company hits a hard block mid-run, you'll see a set_status_message with a partial count — we never silently return an empty dataset.Q: Why does the Actor fail loud instead of returning an empty dataset?
Ready to run it?
Open the listing on Apify, paste the input above, and watch rows land. If it ever breaks, it is our problem before it is yours.
Related Actors