Job Postings Aggregator — ATS Evidence
Pricing
from $1.70 / 1,000 job postings
Job Postings Aggregator — ATS Evidence
Normalize current public job postings from known Greenhouse, Lever, or Ashby board tokens or bounded company-domain ATS detection. Rows include source evidence, attribution, freshness, confidence, gaps, billing semantics, and a manual review action. A listing does not prove growth or buying intent.
Pricing
from $1.70 / 1,000 job postings
Rating
0.0
(0)
Developer
Tim Zinin
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
11 days ago
Last modified
Categories
Share
Job Postings Aggregator — public ATS evidence for recruiting and company research
Turn known Greenhouse, Lever, or Ashby board tokens — or a list of company domains — into one normalized row per unique current job posting. Each delivered role carries a direct source link, retrieval evidence, freshness, company-board attribution, confidence, interpretation gaps, stable IDs, billing semantics, and a recommended manual review action.
Use the result to build recruiting shortlists, map where a market is hiring, enrich an account-research queue, or watch a portfolio of companies. Treat it as evidence that a role appeared on a public board at request time. A posting does not prove headcount growth, a new vacancy, budget, expansion, buying intent, or that the position will be filled.

What you get
- Two ways in. Already know the ATS? Use
items(provider:companytokens) — one HTTP call per company. Only know the company's domain? Usedomains— this Actor checks the company's own careers page for its ATS, then verifies a slug guess if that fails. Mix both in the same run. - Six systems on the domain path. Greenhouse, Lever, Ashby, Workable, Rippling and Workday —
itemsstill covers the first three directly (unchanged, one request each);domainscovers all six via automatic detection. - A
domainsrole you can't vouch for still ships — just for free. When this Actor finds a company's ATS via the domain-slug fallback rather than a link on the company's own careers page, it checks that board's own declared owner against your domain before charging for it. Real example:atlas.comresolves to a genuine, non-empty Ashby board, but that board declares its own company website asatlascard.com— a different company most likely owns it, so every job from it is delivered in full and never billed.itemsroles are unaffected — you named the provider and slug yourself, nothing to verify. See Pricing and Output below. - Current role observations, normalized. Title, location, department, posting date and direct apply URL use one shape. Token mode reads a complete single-feed response within the documented 3 MB limit. Paginated Workday and Rippling domain results can reach a bounded read depth and disclose
resolved-truncatedinstead of pretending the list is complete. - Evidence, not a black box. Successful role rows expose the source URL, retrieval time, HTTP status, response bytes, record count, ownership evidence, freshness, confidence reasons, known gaps, and a manual next action.
- No login or private credentials. Token mode calls fixed public ATS JSON endpoints. Domain mode may first read public HTML on the submitted company's careers pages, then uses public ATS data. Requests are bounded and domain fetches use SSRF and DNS-rebinding guards.
- Exact delivery and duplicate control. The same provider, board and job ID is delivered once even if it arrives through both
itemsanddomains. Paid delivery requires the exact linked Dataset/pay-per-event receipt; ambiguity stops the run withreplaySafe: falseinstead of risking a second charge. - Built for lists. Concurrency up to 20, up to 100 companies per run per field, so tracking a whole sector's hiring is a single run.
- Run-level reconciliation. KVS
OUTPUTrecords requested and unique queries, successful and failed queries, paid and free rows, duplicate suppression, withheld work, partial state, fatal ambiguity, budget state, and replay safety. - Apify-native delivery. Schedule it, monitor it, call it from the API or MCP server, export JSON/CSV/Excel, or route results through webhooks, Make, Zapier, n8n, Sheets, a CRM staging table, or your own code.
Who buys this — and what they do with it
Recruiters and staffing agencies
Start from companies you already cover, retrieve their current public roles, filter by title, department and location, then open the cited job before contacting anyone. The value is faster market mapping and less manual careers-page checking — not an invented contact record or a guarantee that the employer wants agency help.
Small B2B agencies and founder-led sales teams
Add a current role observation to account research before a human decides whether the role creates a relevant question. A security role may justify researching the company's security program; it does not prove security-software budget or purchase intent. Combine the role with fit, relationship history, independent company context, suppression lists and lawful contact policy.
Market researchers and competitive-intelligence teams
Normalize public hiring pages across a buyer-defined company list. Schedule recurring runs and compare saved observations in your own warehouse to study listing changes. One run is a snapshot; this Actor deliberately does not call one snapshot a trend.
Investors, accelerators and portfolio operators
Review current role mix across a known portfolio or thesis list. Use department and location as research directions, then verify the source and company identity. Open roles are operational observations, not audited headcount, payroll, growth or financial guidance.
Data and RevOps teams
Use stable IDs, source evidence and KVS OUTPUT to stage results before CRM mutation. The Actor returns no personal email, phone number, applicant record or private ATS data. It is an enrichment component, not a fully qualified lead decision.
What this Actor is — and is not
It is a bounded collector and normalizer for public job-board observations. Direct token mode supports Greenhouse, Lever and Ashby. Domain detection can identify Greenhouse, Lever, Ashby, Workable, Rippling or Workday using a first-party careers-page link or a disclosed slug-guess fallback.
It is not a general web crawler, candidate database, contact finder, job-description scraper, applicant tracker, employer-of-record verifier, growth detector, intent-data provider or automatic outreach engine. It does not expose private applications, recruiter identities, salary when absent, filled-role outcomes, historical change by itself, or every ATS on the market.

How the evidence workflow works
- Validate before source work. Input must be an object containing 1–100 strings in
items,domains, or both. Unsupported providers, malformed tokens, non-string values and fractional or out-of-range concurrency fail visibly instead of being silently coerced. - Deduplicate with provider semantics. Greenhouse and Ashby board tokens are case-folded because those paths are case-insensitive; Lever case is preserved. Domains are normalized. Duplicate input count is written to
OUTPUT. - Request only what you selected. Token mode calls the fixed public provider endpoint. Domain mode checks guarded public company pages and bounded ATS candidates. Mixing the modes is supported.
- Fail closed on source shape. Responses have a 20-second timeout and a 3 MB token-mode cap. Content type and provider-specific JSON shape are validated. Truncated or malformed HTTP‑200 responses become source errors, never believable empty boards.
- Resolve and disclose identity. A first-party careers-page link is retained as primary evidence. Slug guesses are checked against ATS-declared owner signals; mismatch or inconclusive attribution is delivered free for manual review.
- Normalize without inflating the claim. Provider fields map to title, location, department, URL and posted time. Stable entity, observation, event and evidence IDs are attached.
- Suppress cross-mode duplicates. Delivery identity uses provider, canonical board token and job ID or URL. The same job discovered from both input paths is not delivered or charged twice.
- Attach decision context. Every successful job row explains freshness, single-observation change semantics, evidence coverage, confidence reasons, data gaps, billing status, and the next manual action.
safeToAutomateis alwaysfalse. - Deliver and reconcile. Paid rows use one linked Dataset/PPE call. The runtime requires the exact Apify aggregate receipt. Any ambiguous push or receipt is fatal, not automatically replayed, and appears in
OUTPUTwithreplaySafe: false.
How to run it
- Click Try for free — no card needed on the free plan.
- Either paste
provider:companytokens into Companies (ATS tokens) (e.g.greenhouse:stripe,lever:spotify,ashby:ramp), or paste bare domains into Companies (bare domains) (e.g.figma.com,ramp.com) — or both. - Press Start. Results appear in the dataset — read them in the UI, pull them from the API, or have a webhook push them onward.
Pricing
Pay-per-event: $0.005 per run start + $0.002 per role found. No monthly seat, no minimum. 100 roles cost about $0.21; 1,000 roles about $2.01. items roles are always billed at this rate — you named the ATS yourself, nothing to verify. A domains role resolved via its own careers-page link (Method A) is billed the same way — the company already named this board itself.
A company with no public board (items) or a domain this Actor could not resolve to any ATS (domains) is still logged with found: false and the reason — and it is not charged for.
One more free case, added 04.08.2026, domains only: when this Actor identifies a company's ATS via the domain-slug fallback (Method B) instead of its own careers-page link, it checks that board's own declared owner against the domain you asked for before billing the role. Confirmed match — billed, same as always. Confirmed mismatch, or the check itself couldn't be run — the role still ships to your dataset in full, just never billed. Real example: atlas.com resolves to a genuine, non-empty Ashby board, but that board's own page declares its company website as atlascard.com, not atlas.com — every job from it is free. See the atlas.com row in Output below, and FAQ for what this check can and can't prove. This never applies to items — you pay for roles actually delivered via a board you named yourself, or one this Actor confirmed (or found first-party) belongs to the domain you asked for.
Input
| Field | Required | What it does |
|---|---|---|
items | no* | One entry per company, format provider:company. Provider is greenhouse, lever or ashby; company is the board's own slug (the part in the careers URL, e.g. jobs.lever.co/spotify → spotify). Up to 100 per run. |
domains | no* | One entry per company, a plain domain or full URL — no need to know its ATS. Detected automatically (Greenhouse, Lever, Ashby, Workable, Rippling or Workday). Up to 100 per run. |
maxConcurrency | no | How many companies to check in parallel, 1–20 (default 5). Applies to the combined workload of items + domains. |
* At least one of items or domains must have an entry.
{"items": ["greenhouse:stripe","lever:spotify","ashby:ramp"],"domains": ["figma.com","ramp.com"]}
Output
One dataset row is delivered per unique current role observation. Free diagnostic rows explain unresolved, empty, truncated or failed inputs. The compatibility fields stay intact; the evidence and decision fields are additive. This is a real items row from an earlier production run (the newer evidence fields shown after it are generated from that observation at runtime):
{"input": "greenhouse:airtable","found": true,"provider": "greenhouse","company": "airtable","jobId": "8391589002","title": "Account Executive, SLED","location": "Austin, TX; Remote - US","department": null,"url": "https://job-boards.greenhouse.io/airtable/jobs/8391589002","postedAt": "2026-01-26T22:00:52.000Z","attributionConfirmed": null,"attributionNote": "Provider and slug were specified directly on input — this Actor performed no domain resolution or ownership verification for this row.","scrapedAt": "2026-08-04T16:48:07.640Z"}
The same successful observation now also carries this machine-readable decision context:
{"inputMode": "token","entityId": "job_<stable hash of provider, board and job>","observationId": "observation_<stable hash of job and observation time>","eventId": "event_<stable hash>","observedAt": "<run observation time>","freshness": {"observedAt": "<run observation time>","postedAt": "2026-01-26T22:00:52.000Z","postedAgeDays": "<calculated integer or null>","basis": "live_public_ats_board_at_request_time"},"change": {"basis": "single_observation","previousObservationAvailable": false,"delta": null},"evidence": [{"evidenceId": "evidence_<stable hash>","provider": "greenhouse","url": "https://boards-api.greenhouse.io/v1/boards/airtable/jobs?content=false","retrievedAt": "<source retrieval time>","httpStatus": 200,"contentType": "application/json","responseBytes": "<measured bytes>","outcome": "ok","recordCount": "<validated role count>"}],"evidenceCoverage": 100,"confidence": {"score": 70,"level": "medium","reasons": ["The buyer supplied the ATS provider and board token directly; company ownership was not independently verified.","Machine-readable retrieval or resolution evidence is attached."]},"recommendedAction": "Open the cited role, confirm company and posting context, then use it as one research input rather than an automated intent signal.","safeToAutomate": false,"billing": {"event": "result-found","billable": true,"unit": "one_confirmed_delivered_job_posting_row"},"observationSemantics": {"observed": "A role currently appeared on the selected public ATS board at request time.","doesNotProve": ["headcount growth", "new hiring demand", "budget", "business expansion", "buying intent", "role fulfillment"]}}
Note attributionConfirmed: null here — on an items row that means "not applicable", and
the row is billed exactly as normal (found: true). It reads the same as a domains
row's "couldn't verify" null, but the two are never the same claim — see the field table
above and the atlas.com row below for the domains-mode meaning of null.
| Field | What it means |
|---|---|
input | The provider:company token or domain you passed |
found | true marks a billed row, false a free one. Before 04.08.2026 this meant "the board returned at least one open role"; as of the case below, a genuine domains role (real title/url/jobId) can carry found: false when it was delivered free-by-policy — see atlas.com below. Every items role and every Method A domains role is still found: true. |
provider | greenhouse, lever, ashby, workable, rippling or workday |
company | The board's company slug (typed directly via items, or auto-detected via domains) |
jobId | The ATS's internal job ID |
title | Role title |
location | Office/remote location as listed |
department | Team/department as listed, when the board publishes one |
isRemote | Whether the role is remote — only set on rows found via domains; absent on items rows |
url | Direct apply/posting URL |
postedAt | ISO timestamp of when the role was first published |
resolvedVia | How a domains row's ATS was identified: careers-page (Method A, found a direct link on the company's own site) or slug-guess (Method B, verified by real, non-empty postings). Absent entirely on items rows — that absence is what tells the two input modes apart when attributionConfirmed reads null on both (see below). |
attributionConfirmed | Only meaningful when resolvedVia is present (i.e. a domains row). true on every Method A row and on a Method B row whose board declared owner matches your domain — both billed. false on a Method B row whose declared owner names someone else — free (the atlas.com row below). null on a Method B row where the check could not be run at all — also free, a different fact from false, never conflated with it. On an items row, attributionConfirmed also reads null, but means something else entirely: "not applicable" — you named the provider and slug directly, there was nothing to verify, and the row is billed normally. Check resolvedVia's presence, not the value of attributionConfirmed alone, to tell these two nulls apart. |
attributionNote | Human-readable explanation of the value above. On an items row it says plainly that no resolution or ownership verification was performed for this row. |
scrapedAt | When this Actor fetched the row |
inputMode | token or domain; use this instead of inferring the path from attribution fields |
entityId | Stable job identity derived from provider, board and job ID or URL; useful for joins and cross-run storage |
observationId | Stable identity for this job at this run's observation time |
eventId | Stable identity for the open-role observation event |
observedAt | One run-level timestamp applied consistently to this observation |
freshness | Observation time, provider-supplied posting time, calculated age when possible, and the freshness basis |
change | Explicitly says this row is a single observation with no built-in prior baseline or fabricated delta |
evidence | Source or resolution receipts with stable evidence IDs, URL, retrieval time, response facts, outcome and count when observable |
evidenceCoverage | Coverage score for attached machine-readable source evidence; not a probability that the employer will hire |
confidence | Score, level and reasons about the observation and attribution; separate from commercial fit or intent |
dataGaps | Important facts this source cannot establish, including growth, budget, intent and role outcome |
recommendedAction | Manual verification or research step appropriate to the row's attribution state |
safeToAutomate | Always false; this observation alone is not sufficient for autonomous CRM mutation or outreach |
billing | Whether the row is billable, the event name or null, exact commercial unit and reason |
observationSemantics | Compact statement of what was observed and which stronger conclusions are unsupported |
Domain mode — confirming a board actually belongs to the domain you asked for
A domains role found via the slug-guess fallback (Method B) is real and non-empty the
moment it's found, but that alone doesn't prove the board belongs to the domain you asked
for. Before billing it, this Actor checks the board's own declared owner against your
domain. Confirmed — real row, figma.com, resolved via its own careers-page link
(Method A, always billed, nothing to check):
{"input": "figma.com","found": true,"provider": "greenhouse","company": "figma","jobId": "5364702004","title": "Account Executive, Emerging Enterprise (Berlin, Germany)","location": "Berlin, Germany","department": null,"isRemote": false,"url": "https://boards.greenhouse.io/figma/jobs/5364702004?gh_jid=5364702004","postedAt": "2024-11-01T10:05:10.000Z","resolvedVia": "careers-page","attributionConfirmed": true,"attributionNote": "The company's own careers page linked directly to this job board — primary-source evidence, nothing left to independently verify.","scrapedAt": "2026-08-04T16:48:09.880Z"}
Not confirmed — real row, atlas.com, same run, Method B, delivered but free (
found: falsejobId, real url — never withheld, only
unbilled):
{"input": "atlas.com","found": false,"provider": "ashby","company": "atlas","jobId": "dae00fcb-35a5-4559-8114-7553138b3ea3","title": "Founding Applied AI Engineer","location": "San Francisco","department": "Engineering","isRemote": false,"url": "https://jobs.ashbyhq.com/atlas/dae00fcb-35a5-4559-8114-7553138b3ea3","postedAt": "2026-02-24T18:52:51.098Z","resolvedVia": "slug-guess","attributionConfirmed": false,"attributionNote": "Ashby's job board declares its own company website as atlascard.com, which does NOT match the requested domain atlas.com — this board most likely belongs to a different company.","scrapedAt": "2026-08-04T16:48:11.460Z"}
A third case, just as free but a different fact: attributionConfirmed: null on a
domains row (resolvedVia still present) means this Actor could not tell either way —
either the check couldn't be run at all, or the board's declared name is inconclusive
rather than confidently wrong. That second flavor is real and live: chime.com resolves
to its own, genuine Greenhouse board — the company never changed its name — but that
board is legally named "Chime Financial, Inc", not "Chime":
{"input": "chime.com","found": false,"provider": "greenhouse","company": "chime","jobId": "8609153002","title": "Analyst, Investor Relations","location": "San Francisco, CA, USA","department": null,"isRemote": false,"url": "https://boards.greenhouse.io/chime/jobs/8609153002?gh_jid=8609153002","postedAt": "2026-07-22T18:36:41.000Z","resolvedVia": "slug-guess","attributionConfirmed": null,"attributionNote": "Greenhouse's job board is named \"Chime Financial, Inc\", which STARTS WITH the requested domain chime.com but adds a real word this Actor does not strip (a business descriptor, not legal boilerplate) — this looks like it could be your company, but a name alone does not prove it: Greenhouse does not publish this board's owner website, and a genuinely unrelated company with a similar name would read exactly the same way.","scrapedAt": "2026-08-04T17:32:04.760Z"}
This is deliberately null, not false: "Chime Financial, Inc" reads as a genuine match
to anyone who knows the company, but this Actor can't tell that apart from a genuinely
unrelated company that merely shares a leading word — pulse.com's own real Greenhouse
board is named "Pulse Healthcare", the identical shape, and really is a different company
(the actual Pulse is runpulse.com). By name alone these two cases can't be told apart,
so neither gets more confidence than this Actor actually has. See FAQ below for what this
check can and cannot prove.
Domain mode — when a company can't be resolved
A domains entry that doesn't turn into any job rows still gets exactly one free row, with found: false and a resolutionStatus that says why — never lumped into a generic "not found":
{"input": "some-company.com","found": false,"provider": null,"company": null,"resolutionStatus": "unresolved","error": "could not identify this company's applicant-tracking system...","scrapedAt": "2026-08-04T15:20:40.574Z"}
resolutionStatus | Meaning |
|---|---|
resolved-zero | Found the company's ATS board — it genuinely has 0 open roles right now |
unresolved | Could not identify an ATS for this domain — NOT the same as "no jobs", just "don't know" |
source-error | Every attempt failed to even reach a server (network/timeout) — NOT a confirmed "no ATS", retry later |
invalid-domain | The entry didn't look like a real domain — no network call was made |
resolved-truncated | The board paginates (Workday/Rippling) and had more roles than this Actor's default read-depth — the rows already delivered are real, just possibly incomplete |
Run reconciliation in KVS OUTPUT
The Dataset answers “which rows were delivered?” KVS OUTPUT answers “did the whole run finish cleanly, and is a replay safe?” Check both before downstream automation.
{"status": "COMPLETE","observedAt": "<run observation time>","requestedQueryCount": 3,"uniqueQueryCount": 3,"duplicateInputCount": 1,"processedQueryCount": 3,"successfulQueryCount": 3,"failedQueryCount": 0,"unprocessedQueryCount": 0,"observedJobCount": 127,"confirmedDeliveredJobCount": 127,"paidJobCount": 127,"freeByAttributionPolicyJobCount": 0,"localNonMonetizedJobCount": 0,"duplicateJobCount": 8,"withheldJobCount": 0,"statusRowCount": 0,"statusDeliveryFailureCount": 0,"partial": false,"budgetStopped": false,"fatalError": null,"replaySafe": true,"billing": {"monetized": true,"event": "result-found","linkedReceiptExpectedChargedCount": 2,"datasetItemPriceUsd": 0}}
COMPLETEmeans all unique queries were processed without failed queries or withheld work.PARTIALmeans at least one source query failed or work remained. Keep the valid rows, inspect status rows and retry only the affected inputs.FATALmeans delivery, billing or budget state became ambiguous.replaySafeisfalse; inspect the Dataset and charged events before any retry.budgetStopped: truemeans the buyer's run cap stopped remaining paid delivery. Already delivered rows remain valid; withheld rows were not delivered or charged.duplicateJobCountcounts successful jobs suppressed across token/domain paths, not source failures.
Integration recipes
Apify API
Send input to the Actor run endpoint, wait for completion, then read the default Dataset and KVS OUTPUT. Keep your Apify token in a secret manager or platform integration — never hard-code it into a public workflow.
curl -X POST \"https://api.apify.com/v2/acts/zinin~job-postings-aggregator/runs?token=$APIFY_TOKEN&waitForFinish=300" \-H 'Content-Type: application/json' \-d '{"items": ["greenhouse:stripe", "lever:spotify"],"domains": ["figma.com"],"maxConcurrency": 5}'
For unattended use, retain the returned run ID. Read the run's defaultDatasetId for rows and defaultKeyValueStoreId record OUTPUT for reconciliation. Do not treat an HTTP-successful run request as proof that every source query succeeded.
JavaScript
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('zinin/job-postings-aggregator').call({domains: ['figma.com', 'ramp.com'],maxConcurrency: 5,});const { items } = await client.dataset(run.defaultDatasetId).listItems();const output = await client.keyValueStore(run.defaultKeyValueStoreId).getRecord('OUTPUT');if (output?.value?.replaySafe === false) {throw new Error('Inspect Dataset and charged events before retrying this run');}const reviewQueue = items.filter((row) => row.jobId && row.safeToAutomate === false);
Python
import osfrom apify_client import ApifyClientclient = ApifyClient(os.environ['APIFY_TOKEN'])run = client.actor('zinin/job-postings-aggregator').call(run_input={'items': ['ashby:ramp'],'maxConcurrency': 3,})rows = list(client.dataset(run['defaultDatasetId']).iterate_items())output_record = client.key_value_store(run['defaultKeyValueStoreId']).get_record('OUTPUT')output = output_record['value'] if output_record else None
Google Sheets or Excel
Export the Dataset from the Apify console as CSV or Excel. Recommended review columns are company, title, location, postedAt, observedAt, confidence.level, attributionConfirmed, url, recommendedAction and dataGaps. Store entityId as text so spreadsheet formatting does not alter it.
n8n, Make, Zapier or webhooks
Trigger the Actor on a schedule or from a new company-list event. Wait for the run to finish, read KVS OUTPUT, then branch:
- continue only when
statusisCOMPLETEor when your workflow explicitly accepts documented partial results; - send rows into a staging table, not directly into an outreach sequence;
- deduplicate downstream on
entityIdand preserveobservationIdfor history; - require a human to open
url, inspectevidenceand confirm company context; - apply your own consent, suppression, territorial and contact-policy checks before CRM or messaging actions.
MCP and AI-agent workflows
An agent can call this Actor through Apify's MCP surface, but the returned row is designed as research evidence, not an autonomous sales instruction. Keep safeToAutomate: false in the prompt context, preserve citations, and require human approval before updating a CRM record or contacting a person.
Scheduling and historical comparisons
To monitor a fixed market, create an Apify schedule with the same normalized company inputs and save each run ID. Compare rows by entityId; compare observations by observationId. A job present this week and absent next week is a candidate non-observation, not proof that the role was filled, cancelled or removed permanently. Provider outages, changed board tokens, pagination depth and attribution changes remain alternative explanations.
A practical weekly workflow is: preserve raw rows → verify OUTPUT → compare stable IDs → inspect added and missing candidates → open the source → annotate the human conclusion. This Actor supplies the first three ingredients; it does not manufacture the last two.
Responsible use, privacy and source limits
- Submit only public company domains and public ATS board identifiers you are authorized to research.
- Respect the source websites' terms, applicable law, contractual restrictions and your organization's data-retention policy.
- Results concern public job postings. Do not combine them with sensitive applicant data, infer protected traits, or use them to make employment decisions about individuals.
- The Actor does not collect applications, resumes, private candidate records, personal emails or phone numbers.
- Public availability does not create permission to contact a company or person. Apply consent, suppression and jurisdiction-specific marketing rules separately.
- Store source URLs, evidence and observation times with any derived conclusion so another reviewer can audit it.
- Do not label a company “growing,” “funded,” “hiring urgently” or “ready to buy” solely from these rows.
- Source systems can change, remove fields, return stale postings, rate-limit requests or expose incomplete data. Use
evidence,resolutionStatus,dataGapsandOUTPUTinstead of hiding those limitations.
Related tools
Related tools for adjacent workflows in jobs and hiring.
| Actor | What it does |
|---|---|
| Company Hiring Radar | Pair it in the jobs and hiring workflow: Pull every open role a company is hiring for from its public job board (Greenhouse, Lever, Ashby) and turn... |
| XING Jobs (DACH) Scraper | Pair it in the jobs and hiring workflow: Walk xing.com's own job sitemap and pull public job listings from Germany/Austria/Switzerland: title,... |
| jobs.ch Swiss Jobs Scraper | Pair it in the jobs and hiring workflow: Search jobs.ch (Switzerland) by keyword and get public job listings: title, company, location, employment... |
| Layoff Tracker | Pair it in the jobs and hiring workflow: Track recent tech layoffs by company name or sector (e.g. "fintech", "AI") straight from Google News — a... |
| Computrabajo LatAm Jobs Scraper | Pair it in the jobs and hiring workflow: Search Computrabajo (Mexico, Colombia, Chile, Argentina, Peru) by keyword and get public job listings:... |
FAQ
Does it need an API key / login? No — every ATS this Actor talks to (Greenhouse, Lever, Ashby, Workable, Rippling, Workday) publishes its job board as public keyless JSON.
How fresh is the data? Live at request time — the same feed that powers the company's own careers-page widget.
What if a company has no public board on a given provider (items), or its ATS can't be identified (domains)? The row says so (found: false, plus resolutionStatus on a domains row) instead of failing the whole run, and it's never billed.
How does the ownership check on domains work, and what can't it prove? Once the
slug-guess fallback (Method B) already found a real, non-empty board, this Actor takes one
more step before billing the role: it reads the board's own declared owner and compares it
to the domain you asked for. Ashby publishes a real second domain (publicWebsite) —
atlas declares atlascard.com, which is how this Actor knows atlas.com most likely
isn't the real owner. Greenhouse, Lever, Workable and Rippling only publish a company
name, not a second domain — so on four of these five providers, a coincidental name
match (an unrelated real company that happens to share a name with the one you asked
about) could in principle still pass; there is no stronger evidence those four APIs
publish. This check never runs on items (you named the board yourself — attributionConfirmed reads null meaning "not applicable", not "unverified", see Output above) and never runs on a domains role resolved via its own careers-page link (Method A — already primary-source evidence).
Why does chime.com come back attributionConfirmed: null instead of true, when it's
genuinely Chime's own board? Because the board's declared name is legally "Chime
Financial, Inc" — this Actor's name comparison strips real legal suffixes (Inc, Ltd,
GmbH...) but deliberately does not strip ordinary business words like "Financial" (a
growing strip-list eventually swallows a real brand word too). The name starts with the
requested domain's own label plus a real word this Actor won't guess past, so it lands as
inconclusive — never a confident true, never a confident false either. It can't
become true because pulse.com's own real board is named "Pulse Healthcare" — the
identical shape — and is a genuinely different company; by name alone a "Brand + business
word" board can't be told apart from one that belongs to someone else. You still get every
role from a null board in full — see Pricing above.
items or domains — which should I use? If you already know the ATS, items is one HTTP call per company — use it. If you only know the company's domain, use domains; it costs a few extra requests per company to identify the ATS (still never billed on failure), then aggregates the same way.
Can I call it from an AI agent? Yes — standard Apify Actor, callable from the Apify API, the SDK, or the Apify MCP server.
What this is NOT. It does not cover ATS platforms beyond the six above (SmartRecruiters, Recruitee and Personio are deliberately excluded — their robots.txt disallows automated collection), and it does not read the full job description text. domains reads up to a fixed depth on paginated boards (Workday, Rippling) — see resolved-truncated above; for a configurable read-depth on very large paginated boards, use this Actor's sibling, Careers Page Scraper. Not a guarantee that a billed domains Method-B role's board is provably yours on every provider — Ashby's check compares a real domain, but Greenhouse, Lever, Workable and Rippling only ever expose a company name to check against, the strongest evidence those four systems publish (see FAQ); when even that name doesn't match, the role ships anyway, just free.
Found a wrong result, or need a check we don't run? Open an issue on this Actor's page.