Buyer Intent Signals API – Hiring & Missing-Tech Scoring avatar

Buyer Intent Signals API – Hiring & Missing-Tech Scoring

Pricing

$60.00 / 1,000 company reports

Go to Apify Store
Buyer Intent Signals API – Hiring & Missing-Tech Scoring

Buyer Intent Signals API – Hiring & Missing-Tech Scoring

Score accounts 0-100 on buyer intent from public signals: active hiring on public ATS job boards plus a missing tech category you sell into (homepage detection). ICP lead scoring for Clay or your CRM. $0.06 per company with a matched open job board; else free. Not third-party intent surge data.

Pricing

$60.00 / 1,000 company reports

Rating

0.0

(0)

Developer

Siftsmith

Siftsmith

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 hours ago

Last modified

Categories

Share

Buyer Intent Signals — Hiring Velocity + Tech Gap Scorer

Give it a list of companies. Get back one score per company: are they growing (actively hiring) and not yet using a category of tool you sell? That combination — growth without the category you're pitching — is a classic B2B buying-intent signal, the kind Bombora and 6sense charge four/five figures a month for.

It combines two Siftsmith Actors that already run in production, Hiring Signals (public ATS job-board data) and Tech Enricher (public homepage technology detection), and turns their two outputs into one decoded score instead of two raw dumps you'd have to cross-reference by hand.

Quick start

Input:

{ "companies": ["datadoghq.com", "stripe.com", "lever:palantir"], "targetCategory": "CRM" }

One row per company. A run on 2026-10-14 returned this for datadoghq.com (trimmed):

{ "company": "datadoghq.com", "hiringFound": true, "ats": "greenhouse", "openJobs": 439, "postedLast30d": 119,
"hiringScore": 71, "techFound": true, "hasTargetCategory": false, "buyerIntentScore": 100 }

Datadog is hiring fast and no CRM shows on its homepage, so its score is 71 × 1.5 = 107, capped at 100.

  • Price: $0.06 per company with a public job board that has open jobs. Every other row is free, including no board, a board naming a different company, a failed job-board lookup and duplicates. There's no start fee. Details are under "Pricing".
  • Best input: domains (stripe.com). A domain beats a bare name, because the tech half needs a real website. Workday and Rippling boards must be passed explicitly (workday:tenant:wdN:site, rippling:slug or the board URL); they are never auto-detected. Board syntax like lever:palantir has no domain, so it's scored on hiring alone (techFound: false).
  • Pasted spreadsheet rows: one company per line. A line with several fields (split by tabs, |, ; or quoted CSV cells) is looked up by, in order: a job board in any field (a board URL or greenhouse:acme); a website or work email that agrees with the company name; otherwise the first field, skipping row numbers and company pages on directories (LinkedIn, Crunchbase). So 1 | Adyen | Amsterdam | adyen.com is looked up as adyen.com and Alphabet | abc.xyz as Alphabet. A row with no website, email or job board whose first two fields are each one word written like a name (Jane, Doe; not an acronym like IBM or a word like Corp or Labs) reads as a person's name. A row whose first field is a common US first name, in any letter case, also reads as a person's name, even when the next field is an acronym or several words: David | IBM is free, and TAYLOR | BROWN | ACME CORP is looked up as ACME CORP. This also frees a company named like a person, such as Harper | San Francisco. A row whose second field is a common US first name after a one-word surname also reads as a person's name, in any letter case: FERGUSON | JOHN | IBM is free, and parsons | mary | acme corp is looked up as acme corp. This also frees a company whose second field is a city or other word that is also a first name, such as TESLA | AUSTIN. A row of three or more fields whose first field is one word is never looked up by that first field when its second field is empty, a placeholder such as N/A, - or ?, or reads like a given name however it is punctuated or accented: initials, titles, suffixes, nicknames and joined names included (Dr. John, John Q. Jr., John (Jack), J.-P., John/Jack, Sarah (she/her)). A second field of two or three letters is always read as initials (AB, SE, LTD). A second field with a digit, or with a word such as Group, Services, Holdings, Corp or GmbH, is not read as a given name. So Ferguson | John Q. | IBM, Stevens | | IBM and PARSONS | N/A | IBM are free. A company row of that shape, such as IBM | | Armonk, STRIPE | DUBLIN | FINTECH or Stripe | N/A | Fintech, is free too, unless a later field is the same name plus a legal form or company word: STRIPE | DUBLIN | STRIPE INC is looked up as STRIPE. A person's row is looked up only by a later field of two or more words that ends in a legal form or a company word such as Inc, Corp, Ltd, GmbH, Group, Technologies or AI: Jane | Doe | Acme Corp is looked up as Acme Corp. Otherwise the row is free: Jane | Doe | Stripe, Jane | Doe | London, Stripe | Dublin | Fintech and Stripe; Plaid; Ramp read the same way. So is a two-field company row like Adyen | Amsterdam or Goldman | Sachs. So is a row whose first field is one word written like a name followed by a company field (two or more words ending in a legal form or company word, as above), unless that field is the same name plus those words: David | Acme Corp and Notion | Software Company are free; Stripe | Stripe Inc and Notion | Notion Labs are looked up as Stripe and Notion. A LinkedIn profile link (linkedin.com/in/…) also makes a row a person's row, looked up only by a company field: David | linkedin.com/in/dsmith | Acme Corp is looked up as Acme Corp. Add the company's website to have such a row looked up. If the line also has a company website or work email, a job board found by that name counts only when it ties to that website: the board lists it, the board's jobs link to it or mention it, or the website links the board. Otherwise the line is free: Plaid, adyen.com is free, because Plaid's board doesn't point to adyen.com. A line looked up by its name that has no website, only a personal email address (Gmail, Outlook, Yahoo and the like), is free too, because nothing in it confirms the name is a company: lead lists often put a person's first name first. So David, Smith, david@gmail.com and Stripe, jane@gmail.com are both free; add the company's domain (Stripe, jane@gmail.com, stripe.com) and the line is looked up by that domain. Names like Acme, Inc. contain a comma, so plain commas split a line the same way only when it has a job board, a website or work email that agrees with the name, or a name first and a website or work email after it: Adyen, adyen.com is looked up as adyen.com and Alphabet, abc.xyz as Alphabet, while Acme, Inc. stays one name.
  • Target category: optional. Leave it out to score hiring alone.

What you get per company

FieldMeaning
hiringFound / hiringScore / openJobs / postedLast30d / atsSame hiring signal as Hiring Signals: is there a public job board, how many open roles, how many posted in the last 30 days, 0–100 hiring score (volume + freshness)
bulkRepublishtrue when a board with 20+ open roles has more than half of them published within one 24-hour window (any 24 hours, so a burst across midnight UTC counts), the pattern of a board migration or re-import rather than a hiring surge (a brand-new board launched within 24 hours is flagged too). Those roles still count in openJobs and postedLast30d (the job board's own dates) but not as fresh in hiringScore, so a re-imported board doesn't read as surging intent
openJobsCapped / openJobsReportedopenJobsCapped is true when the board has more open roles than one report covers (1,000 on Workday, or fewer if the board answers too slowly to page through within 2 minutes); openJobsReported is then the job board's own total (null when it doesn't report one), and hiringScore's freshness is taken of that total (see "Scoring")
freshnessLowerBoundtrue only on a capped board where every fetched role was posted in the last 30 days: postedLast30d and the freshness part of hiringScore are then lower bounds, same as in Hiring Signals
matchConfidence / boardCompanyNameHow sure the job-board match is, same as Hiring Signals: explicit (you passed ats:slug or the board's URL), high (the board's own company name matches your input; for a domain, the board must also point at that domain: the website it lists, or its job links, are on it, or your domain redirects to that website, or that website redirects to your domain, e.g. an old domain the company moved from. The website is the "Home Page" link on Lever boards, the "Company Website" link on a Breezy HR board's careers portal, or the legal-notice link on Personio's), medium (unchecked: the board gives no name, which for a domain needs its jobs to mention that domain or the domain's site to link the board; a domain's board that lists no website is charged only when its job descriptions link that domain or the domain's homepage or careers pages link the board or list its job ids, or the careers site the board lists is on the domain, or is one named for it (wise.jobs for wise.com) that the domain's homepage or careers pages link; also a board under the domain's name whose own name starts with it and goes on, e.g. chime.com finding Greenhouse's "Chime Financial, Inc", charged only when at least two of its jobs, and half of them, give the domain as a link or email address or the domain's site links the board; a board named by the domain's get/go/use stem, e.g. gomotive.com finding "Motive", is high with the same tie), low (it names a different company, its website is on a different domain and doesn't redirect to yours, e.g. census.com finding Breezy HR's "CENSUS SA" at census-labs.com, or it is a Personio board with no name at all, or for a domain a nameless board nothing ties to it, e.g. relay.com finding Lever's relay, or a possible board found only under your name minus a trailing word like Bank/Enterprises/Holdings, e.g. Monzo Bank Ltd finding Greenhouse's "Monzo", or an Ashby board found from a name or domain, e.g. ramp.com finding ashby:ramp: an Ashby board is matched only when you pass it as ashby:slug or its URL; not used and not charged). See "Job-board matching" below
techFound / technologies / technologiesByCategorySame tech-stack signal as Tech Enricher: technologies confirmed from the homepage's tags, scripts and headers, grouped by category (CMS, CRM, Analytics, Marketing, Support, …). A homepage that was fetched but showed no confirmed technology (apple.com) is techFound: false with a techNote saying so: an empty stack is unknown, not an absence
cspOnlyTechnologiesVendors named only in the site's Content-Security-Policy or a resource hint (preconnect, dns-prefetch): allowed to load, often through a tag manager, but not confirmed on the page. Not part of technologies; they do count as present for hasTargetCategory, so an unconfirmed vendor never raises the score
hasTargetCategoryOnly present when you set Target technology category. true if the detected stack includes that category (a vendor in cspOnlyTechnologies counts), false if a confirmed stack doesn't, and null when the stack is unknown (the tech lookup failed or confirmed nothing; see techNote). false means the category wasn't seen on the homepage, not that the company doesn't use it: tags loaded only from script bundles or on other pages can be missed (see Limitations)
buyerIntentScoreThe combined score. See "Scoring" below for the exact formula — no hidden weights
domain, domainGuessedThe domain used for the tech lookup, and whether it came from a bare company name rather than your input: guessed, or taken from the website the matched job board lists (see "Input" below)

Scoring (exact formula, no black box)

buyerIntentScore = hiringScore // no target category set
buyerIntentScore = hiringScore // target category set AND detected in their stack
buyerIntentScore = round(hiringScore × 1.5), capped at 100 // target category set, at least one technology confirmed (techFound), AND category NOT detected
buyerIntentScore = hiringScore // target category set but tech lookup failed or confirmed nothing (unknown, never guessed as an absence)

hiringScore is Hiring Signals' own 0–100 score: round(100 × (0.6 × volume + 0.4 × freshness)), where volume is a log-scaled open-role count (a capped board's openJobsReported; saturates ~300 roles) and freshness is the share of roles posted in the last 30 days. On a bulkRepublish board, the roles published in the bulk 24-hour window don't count as fresh. On a capped board (openJobsCapped: true) the share is of the board's own total (openJobsReported), not of the 1,000 roles fetched: Workday lists newest roles first, so the fetched roles alone would over-state freshness (a board reporting 1,500 whose first 1,000 are all recent scores 87, not 100, and is flagged freshnessLowerBound).

The scoring is fully transparent: a documented 1.5× boost when a company is both growing and missing the category you sell. Every score is explainable, so your team knows exactly why an account is at the top of the list.

Input

  • Companies: same format as Hiring Signals — names (Datadog), domains (stripe.com; a careers-style subdomain such as careers.airbnb.com or jobs.stripe.com is looked up as the company's own domain, airbnb.com, for both the job board and the tech stack), or explicit boards (greenhouse:stripe, lever:palantir, ashby:ramp, workable:huggingface, breezy:census, personio:deskbird, workday:tenant:wdN:site, rippling:slug). A job board's own URL (https://jobs.lever.co/palantir, https://jobs.ashbyhq.com/resend, https://boards.greenhouse.io/stripe, https://salesforce.wd12.myworkdayjobs.com/External_Career_Site, …) is read as that explicit board; like ats:slug, it has no company domain, so the tech lookup is skipped. A board prefix with no valid board after it (personio:, lever: acme corp, workday:nvidia) is a malformed input: its row is free, with an error that gives the expected format (personio:<slug> (e.g. personio:deskbird)). SmartRecruiters links are recognised, not read: SmartRecruiters asks automated tools not to read its job API (robots.txt), so such a row is free, with notRead: "robots.txt" and an error that says so.
  • Target technology category (optional): one of the categories Tech Enricher's fingerprints (152 technologies) actually group technologies into, with the number of technologies in each: Analytics 29, CMS 12, Frontend 14, Search 1, Marketing 23, Hosting 11, Support 8, CRM 5, Advertising 12, Ecommerce 6, Recruiting 4, Payments 7, Video 4, Fonts 2, A/B Testing 2, Consent Management 5, Monitoring 3, Security 4. Coverage is uneven: CRM only knows Salesforce, HubSpot CRM, Pipedrive, Zoho SalesIQ and Freshsales, and only when the homepage loads their script (a <script src> or the CSP; a link or a mention doesn't count). A company on any other CRM, or one whose CRM never appears on its homepage, shows hasTargetCategory: false when the rest of its stack is confirmed (null when its stack is unknown). It's a dropdown, not free text, so a typo isn't possible via the Console; a raw API call with an unlisted value is rejected by the input schema before the run starts, not silently mis-scored.

Job-board matching

Company names and domains are matched to job boards the same way as in Hiring Signals: likely board names are tried on each supported ATS, and each board found is checked against the company name it gives for itself. A low match (the board names a different company, e.g. Horizon finding Lever's "Horizon Robotics") is not used as a hiring signal: the row is free, hiringFound: false, with that board's ats, boardUrl and boardCompanyName and an error saying to pass the board explicitly (lever:horizon) if it is the right company. The same free row, with an error starting "Possible job board found under a shorter name", comes back when a name ending in a word like Bank, Enterprises or Holdings (Monzo Bank Ltd) finds a board only under the shorter name (greenhouse:monzo, "Monzo"): that is often a different company, so it's never charged unless the board gives the whole name (Palantir Technologies). An Ashby board is matched only when you give it (ashby:ramp or https://jobs.ashbyhq.com/ramp): Ashby's public job API gives no company name to check a guessed board against, so a board found on Ashby from a name or domain comes back as a free low row with an error naming the board to pass. A medium match (the board gives no name) is used and charged but couldn't be fully checked, so look at boardUrl. For a domain, a board that lists no website is used only when its job descriptions link that domain or the domain's own site links the board; otherwise it is a free low row. A brand with a degree sign is also tried with the sign written out as "grad", the usual German spelling: 1KOMMA5°, or 1Komma5 GmbH typed without the sign, finds personio:1komma5grad ("1KOMMA5°", 320 open roles on 2026-10-01); a board found that way is used only when its own name is the company's. Large enterprises on Workday, SAP SuccessFactors, iCIMS or their own careers pages are often not found by name. Workday works only as an explicit workday:{tenant}:{wdN}:{site} board.

Domain resolution (read this if you pass bare company names)

The tech-stack half needs an actual website to fetch. If your input is already a domain (stripe.com) or explicit board syntax has no domain to give, it's used as-is or skipped. If your input is a bare company name (Datadog, Hugging Face), the domain is guessed as the name joined together + .com (datadog.com, huggingface.com) — the same slug-guessing approach Hiring Signals already uses for job boards. This works for a lot of companies but is not a real domain lookup; it will be wrong for companies whose brand name isn't their domain. domainGuessed: true flags every guessed case so you can spot-check. When the matched job board lists the company's own website (Lever boards do), that site is read instead of the guess, and domain shows it (unless it is only a careers site, or the board's jobs name the guessed domain and not the listed one). When the only board found for a name is an Ashby board found by guessing, no domain is guessed at all: Sierra gives domain: null and techFound: false with the techNote "website unknown: the job board found for this name gives no company website", rather than reading sierra.com (a different company). If a guessed domain redirects to a different company's site, that site isn't fetched and nothing from it is used: the row has techFound: false and a techNote such as "guessed domain <domain> redirects to <site>, likely a different company; tech data not used. Pass the real domain instead.". A redirect is accepted when the site it lands on starts with the guessed name, e.g. huggingface.com → huggingface.co, datadog.com → datadoghq.com. Inputs that are IP addresses, localhost or private-network names are never fetched. Each homepage lookup, redirects included, finishes within 20 seconds; a domain whose homepage redirects to another site that doesn't answer gets a techNote naming that site. A pasted row that carries the company's own website next to its name (Flex, getflex.com, Tia\tasktia.com, or a work email such as Jane Doe <jane@stripe.com>) is read from that site, never from a guess: domain shows it and domainGuessed is false (a personal email address, an address or page on a directory, social or developer platform such as linkedin.com or github.com, or a job board doesn't count as the company's site: the site the board lists, or the name's guess, is read instead, as for a bare name). For accurate results, pass domains directly. Explicit ats:slug inputs (greenhouse:stripe) have no domain information at all — the hiring signal still works, but the tech signal is skipped (techFound: false, techNote explains why).

Pricing

Pay per result: $0.06 per company with a public job board that has open jobs (hiringFound: true). The score is built on the hiring signal, so without one buyerIntentScore is always 0. Companies with no board, a board with no open jobs (one whose only postings are standing invitations such as "General application" or test postings such as "Test Job", or whose real postings all carry a date over a year old, counts as having none), or only a low-confidence board (one that names a different company) are returned free, with any tech-stack data that was found, and an error saying why they weren't charged; so are a malformed board input (personio: with no board name) and an input whose lookup failed with an error. A company whose lookup doesn't finish within 180 seconds (a job board or homepage that stops responding) gets a free row with timedOut: true and an error, so one slow site never holds up the rest of the run. Set a max charge per run and the Actor stops cleanly when it's reached: every input not yet reported still gets a short free row with skipped: true and a reason, so no input goes missing from the dataset. You're never charged more than the max you set. A duplicate of a skipped input gets its own skipped row, never a pointer to a row with no data. The run's status message counts every input once: companies scored, companies with no job-board signal, companies not scored because the charge limit was reached, and duplicate inputs, e.g. "Scored 1 of 3 unique companies; 2 not scored because the charge limit was reached (free); 1 duplicate input (free). 4 inputs in total."

Duplicates are charged once. Inputs are deduplicated on the job board they resolve to (ATS + slug), not on the text you typed: Stripe, stripe.com and greenhouse:stripe are one company, and so are greenhouse:datadog, Datadog and datadoghq.com, even though they carry different domains (or none). Inputs with no job board are deduplicated on their domain. In each group the reported row is the first input, in input order, whose homepage lookup confirmed at least one technology (so Datadog is reported rather than greenhouse:datadog, which has no domain), or the first input if none did. Every other input in the group still gets its own row, free, with duplicateOf set to the reported input. Exact repeats of the same text are collapsed to one row before processing.

Use it in Clay

Clay has a built-in Apify integration, so this works as a per-row enrichment column:

  1. In your Clay table, add an enrichment, search Apify, and choose Run Apify Actor.
  2. Connect your Apify account with your Apify API token (Apify Console → Settings → API & Integrations).
  3. Pick this Actor and enter the input as JSON, putting the row's value into the companies list. Clay's Apify integration guide shows how to insert a column into the JSON.
  4. Run the column. Each row's result comes back into Clay, where you can split fields such as buyerIntentScore into their own columns.

Billing: Apify charges $0.06 per company with an open job board (others are free) to your Apify account, with no per-run start fee. Clay counts the Action on its side but uses no Clay data credits when you bring your own Apify account.

Data sources & compliance

No new data source: reuses the same official public ATS job-board APIs (Greenhouse, Lever, Ashby, Workable, Breezy HR, Workday, Personio, Rippling) as Hiring Signals, and the same public homepage HTML/headers/CSP detection as Tech Enricher (its DNS checks aren't used here). No logins, no scraping of personal data.

Good to know

  • One run, two signals. Uses the same detectors as Hiring Signals and Tech Enricher, cross-referenced and scored for you.
  • Best results with domains. Bare company names are matched to a likely domain; passing the domain gives the most precise results.
  • Homepage-only tech detection, same as Tech Enricher: a tool used only on a subpage (e.g. a CRM widget that only loads in a logged-in app), or loaded only from the site's own script bundles, won't be detected, which can produce a wrong hasTargetCategory: false (and an inflated buyerIntentScore) for a company that actually has the tool. Treat a high score as a strong lead to review.
  • Hiring-score inherits Hiring Signals' own limitations: guessed job-board matches can miss companies on unsupported ATSes (enterprises on Workday, SuccessFactors, iCIMS or custom careers pages are often not found by name; Workday and Rippling need an explicit board), a same-named company's board can come out high, a medium match is unchecked, and postedAt freshness can be inflated by roles reposted one at a time (a whole board re-published within 24 hours is caught: bulkRepublish).
  • No firmographic data (employee count, revenue, funding) — none of that is available from public, unauthenticated sources.

How-to guides

  • Company Jobs: the open jobs behind each hiring score, one row per job, at $0.001 per job row. Run it on your top-scoring companies to see which roles they're hiring for.
  • Hiring Signals and Tech Enricher: the two Actors this score is built from, if you want their full output.

Support

Open an issue on the Actor's Issues tab or email hello@siftsmith.com. Issues are read daily and fixed promptly.