ATS Jobs API: Greenhouse, Lever, Ashby, Workday
Pricing
from $1.50 / 1,000 job postings
ATS Jobs API: Greenhouse, Lever, Ashby, Workday
Monitor open jobs from 10,099 companies on Greenhouse, Lever, Ashby and Workday, with seniority, area and remote-from-Brazil filters. Job postings API with salary, country and work model, searchable by company name. Monitor mode charges only new jobs. No login, no proxy.
Pricing
from $1.50 / 1,000 job postings
Rating
0.0
(0)
Developer
Constancio Dev
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
ATS Jobs API: Greenhouse, Lever, Ashby & Workday job postings
Monitor open jobs from 10,099 companies on Greenhouse, Lever, Ashby and Workday, with seniority, area and remote-from-Brazil filters. One Actor, one output format: each job comes back with company, location, country, work model, salary range, seniority and posting date, and you pay only for the jobs you receive. Schedule it in monitor mode and pay only for jobs that are new or changed since the last run.
Built by Constancio Dev, a small engineering studio focused on data pipelines and B2B automation. constanciodev.com.br
What you get
- A jobs API for 5 ATS platforms. Greenhouse, Lever, Ashby, Workday and InHire, read through their official public job board endpoints. No login, no proxy, no headless browser.
- 10,099 companies searchable by name. The built-in index (checked against each public job
board on 22/10/2026, kept only if it had open jobs) has 3,396 companies on Greenhouse, 1,353
on Lever, 2,225 on Ashby and 3,125 on Workday. Type
StripeorCapital Oneinstead of hunting for the careers URL, or paste any careers page URL orplatform:slug. - Fields you can filter on. Country (ISO code), US and Brazilian state, remote, hybrid or onsite, salary range and currency, seniority, area (backend, data, ML/AI, product...), years of experience required and whether a remote job is open to someone living in Brazil.
- Monitor mode. Run it on a schedule and receive only jobs that are new or changed.
- Safe costs.
maxItemsand the maximum cost per run stop the Actor cleanly, keeping every job already delivered.
Example output
One dataset item per job. Real item from a local test run (22/10/2026):
{"id": "lever:ciandt:8d33fe81-e0c7-4708-9d69-2f1ee89daad3","platform": "lever","company": "CI&T","title": "[Job - 31975] .NET Developer Senior, Brazil","url": "https://jobs.lever.co/ciandt/8d33fe81-e0c7-4708-9d69-2f1ee89daad3","location": "Brazil","country": "BR","work_model": "remote","department": "Centelha","posted_at": "2026-10-22T17:18:11.741000+00:00","salary_min": null,"salary_max": null,"seniority": "senior","area": "backend","remote_scope": "remote_country_specific","remote_open_to_brazil": true,"years_experience": null,"scraped_at": "2026-10-22T18:00:39.302156+00:00"}
The real item also has company_slug, state, employment_type, salary_currency,
salary_period and, unless you turn it off, description. A field the posting does not support
is null, never guessed.
| Field | Meaning |
|---|---|
id | Platform, company and job id. Stable across runs, good for deduplication. |
platform, company_slug | Which ATS and which board the job came from |
country, state | ISO 3166 country code; US state or Brazilian state code when the location allows it |
work_model | remote, hybrid or onsite, as declared by the ATS or written in the location |
salary_* | Range as the posting states it (or parsed from the description): currency code and period (year, month, hour...) |
seniority | intern, junior, mid, senior, staff_plus (staff, principal, tech lead), manager (manager, head, director, VP) or unknown |
area | backend, frontend, fullstack, data, ml_ai, devops_sre, mobile, security, qa, product, design or other |
remote_scope | remote_global, remote_latam_or_americas, remote_country_specific, hybrid, onsite or unknown |
remote_open_to_brazil | true when a person living in Brazil can take the job remotely, false when not, null when the posting does not say |
years_experience | Years of experience required, when stated |
Input examples
1. Remote senior engineering jobs a person in Brazil can take
{"companies": ["greenhouse:anthropic", "ashby:openai", "lever:spotify", "Stripe", "Databricks"],"remoteOpenToBrazil": true,"seniority": ["senior", "staff_plus"],"area": ["backend", "fullstack", "data", "ml_ai"],"maxItems": 200}
2. Daily feed of new jobs for your site or newsletter (schedule it once a day)
{"companies": ["Stripe", "Capital One", "NVIDIA", "ashby:ramp"],"keywords": ["data engineer", "analytics engineer"],"locations": ["United States", "Remote"],"includeDescription": false,"monitorMode": true}
3. Hiring signal for sales: who is recruiting sales roles this week
{"allIndexedCompanies": true,"keywords": ["account executive", "sales development"],"postedWithinDays": 7,"includeDescription": false,"maxItems": 5000}
The third example reads the whole index, which is a long run: raise the run timeout (see Limits).
Input reference
| Field | What it does |
|---|---|
companies | Careers page URLs, platform:slug, or a company name from the index. Empty collects a curated list of 154 companies (Stripe, OpenAI, NVIDIA...). |
allIndexedCompanies | Add every company of the index to the list. |
keywords | Keep jobs whose title contains at least one of these words (case and accents ignored). |
locations | Keep jobs whose location contains one of these, or whose country matches (London, Germany, US). |
remoteOnly | Keep only jobs the posting declares as remote. |
seniority, area | Keep only these levels or areas (values in the table above). |
remoteOpenToBrazil | Keep only remote jobs that a person living in Brazil can take. |
postedWithinDays | Keep only jobs posted in the last N days. Jobs without a date are left out when set. |
maxJobsPerCompany | Newest jobs kept per company after the filters (default 100, 0 = no limit). |
maxItems | Stop after delivering this many jobs in the run (default 50,000, 0 = no limit). |
includeDescription | Include the full description text (default: true). |
monitorMode | Deliver and charge only jobs that are new or changed since the previous run. |
seenWindowDays | Monitor mode: forget a job after it has not been listed for this many days (default 90). |
Limits per run: up to 200 companies, 100 keywords and 100 locations; postedWithinDays up
to 365, maxJobsPerCompany up to 2,000 and maxItems up to 1,000,000.
Accepted company formats:
| Platform | URL | platform:slug |
|---|---|---|
| Greenhouse | https://boards.greenhouse.io/stripe, https://job-boards.greenhouse.io/stripe | greenhouse:stripe |
| Lever | https://jobs.lever.co/spotify | lever:spotify |
| Ashby | https://jobs.ashbyhq.com/openai | ashby:openai |
| Workday | https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite | workday:nvidia.wd5/NVIDIAExternalCareerSite |
| InHire | https://olist.inhire.app/vagas | inhire:olist |
Pricing
Pay per event: $1.50 per 1,000 jobs delivered to the dataset, plus $0.00005 per GB of memory when the run starts. Companies that return no jobs cost nothing, and neither do jobs removed by your filters or, in monitor mode, jobs you already received. Set a maximum cost per run in the run options and the Actor stops when it reaches it.
FAQ
Is it allowed to collect these jobs? The Actor reads only postings that companies publish
openly through the public job board endpoints of their ATS, without login, and respects
robots.txt. Check the terms that apply to your own use of the data.
How does monitor mode work? The Actor keeps a list of the jobs it delivered in a Key-Value
Store of your account, with the date each one was last seen. A job that is still listed and has
not changed is not delivered or charged again. A job that changed its title, location, salary or
description comes back. A job not listed for seenWindowDays days (default 90) is forgotten, so
the list does not grow forever.
Why is a job's remote_open_to_brazil null? The posting says only "Remote" with no country,
region or time zone, so the Actor does not guess.
Can I use it for Brazilian companies only? The companion Actor Vagas Brasil is tuned for jobs in Brazil, with BRL salary and Brazilian states. For one ATS only, see Greenhouse, Lever, Ashby and Workday.
Something is wrong or missing? Open an issue on this Actor's page, or write to suporte@constanciodev.com.br.
Limits
- Only public job boards. Jobs that a company keeps off its public ATS board, or on another ATS, are not covered. The index is a snapshot of 22/10/2026: a company can have changed ATS since, and then you get a clear failure line in the log for that company.
- Run time. Greenhouse, Lever and Ashby return a whole board in one request. Workday needs
one request per job, so a Workday company with the default limit of 100 jobs takes about 3
minutes; up to 10 companies run at a time. A local run of the curated list with no filters
(16/10/2026) took 16 minutes and delivered 12,237 jobs. The full index holds about 880,000
open jobs, far more than the default 1 hour timeout covers: raise the timeout and keep
maxItemsas the cap. When the timeout is near, the Actor stops cleanly and keeps what it delivered. - Classification is rules, not AI.
seniority,area,remote_scopeandremote_open_to_brazilcome from deterministic rules over the title, location and description (see below). A title with no level and no years of experience isunknown. - Salary only when it is written. It comes from the ATS pay fields or the description text; many postings have none.
- Monitor memory is shared. All monitor runs in your account use one list. Two schedules with different filters over the same companies share it, so a job delivered by one is not delivered by the other.
- No contact fields. The output has no recruiter name, e-mail or phone field; the description is the posting text exactly as the company published it.
- Politeness. It identifies itself, waits 1.5 s between requests to the same host and backs
off on HTTP 429/503. Workday sites whose
robots.txtcloses the careers site are left out.
Job classification
Every job gets four extra fields, computed inside the Actor by deterministic rules over the title, location, work model and description. No paid API, no network call, no AI model: the same posting always gets the same answer, and it adds about half a second per 1,000 jobs.
seniorityreads the title first (Senior,Sr.,III,Staff,Principal,Tech Lead,Engineering Manager,Head of,Director,Intern,New Grad,II, PortuguesePlenoandEstagiotoo). "Product Manager", "Account Manager" and "Program Manager" are individual roles, not people managers. With no level in the title, the years of experience the posting asks for decide: up to 1 year isjunior, 2 to 4 ismid, 5 or more issenior. With neither,unknown.areareads the title. Sales, support, recruiting and other non engineering roles areother, and so is an engineering title that names no specialty (plain "Software Engineer").remote_scopecombines the ATS work model, the location text and phrases in the description ("3 days a week in the office", "fully remote", "#LI-Hybrid"). A remote job limited to a country or region (US, UK, EMEA, Europe, APAC) isremote_country_specific; one open to Latin America or the Americas isremote_latam_or_americas; one that says worldwide, global or "international OK", or names no country at all, isremote_global.remote_open_to_brazilistruefor remote jobs open worldwide (explicitly), in Latin America or the Americas, in Brazil, or in a time zone range that includes UTC-3 (for example "UTC-6 to UTC+3"). It isfalsefor hybrid and onsite jobs and for remote jobs limited to another country. A bare "Remote" with no country staysnull.
Measured accuracy, on 150 real jobs from this Actor's own output that were labeled by hand without looking at the rules (another 424 labeled jobs were used to write them):
| Field | Accuracy |
|---|---|
seniority | 89.3% |
area | 96.7% (87.5% on the 32 tech jobs alone) |
remote_scope | 95.3% |
remote_open_to_brazil | 98.7% |
A TF-IDF and logistic regression model trained on the same 424 jobs scored lower on every field (51% to 96%), so the Actor ships the rules only.
Data sources and credits
The company index is built by scripts/descobrir_empresas.py, which reads candidate company
slugs from these openly licensed public lists (each pinned to a commit) and then checks every
candidate against the ATS's own public job board API. Only the validated slugs are kept; no
job text from these lists is copied.
| List | License | Commit |
|---|---|---|
| vanshb03/Summer2027-Internships | MIT, Copyright (c) 2025 Vansh Bataviya | ec34b41 and 5 earlier commits |
| vanshb03/New-Grad-2027 | MIT, Copyright (c) 2025 Vansh Bataviya | acefe9d and 4 earlier commits |
| dreamworkhq/Tech-Internships-2027 | MIT, Copyright (c) 2026 Dreamwork | f7893c0 |
| dreamworkhq/Open-Tech-Internships-2027 | MIT, Copyright (c) 2026 Dreamwork | dab60d4 |
| TrevorDohm/MBA-Tech-Internships-2027 | CC0-1.0 | e73d9b5 |
| ambicuity/New-Grad-Jobs | MIT, Copyright (c) 2026 Ritesh Rana | 51e543d |
| Feashliaa/job-board-aggregator | MIT, Copyright (c) 2026 Riley Dorrington | 136fa9b |
The MIT-licensed lists are used under the terms of the MIT License, which requires keeping
their copyright and permission notices; see each repository's LICENSE file.