Company Tech Stack & Domain Signals avatar

Company Tech Stack & Domain Signals

Pricing

$2.00 / 1,000 domain analyzeds

Go to Apify Store
Company Tech Stack & Domain Signals

Company Tech Stack & Domain Signals

Paste company domains, get one row each: website tech stack (CMS, e-commerce, analytics, marketing tools, CDN, hosting), mail provider and SPF/DMARC/DKIM grade, SaaS verification records, RDAP domain age and registrar, and hiring platform with open-job count. Public data only.

Pricing

$2.00 / 1,000 domain analyzeds

Rating

0.0

(0)

Developer

Signal Scout

Signal Scout

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

21 hours ago

Last modified

Share

Give it a list of company domains. You get one row per domain that shows what the company runs and how it operates, built only from public signals:

  • Website technologies: CMS, e-commerce platform, analytics, tag managers, marketing automation, ad pixels, chat, payments, consent tools, A/B testing, CDN, hosting, frameworks and more. There are about 400 fingerprints in 31 categories, and each detection carries a confidence score and the evidence string it came from.
  • Email and DNS: mailbox provider (Google Workspace, Microsoft 365 and others), email gateways, SPF services (which tools send mail as the domain), DMARC policy and vendor, DKIM on common selectors, MTA-STS, TLS-RPT and BIMI, plus an A–F email-security grade.
  • SaaS footprint: domain-verification TXT records, such as Atlassian, HubSpot, Stripe, OpenAI and Miro.
  • Domain facts (RDAP): registrar, creation, update and expiry dates, domain age in years, status flags and DNSSEC.
  • Hiring signal: which applicant tracking system the company uses (35 ATSes are recognised) and, for 12 of them, the number of open jobs taken from the public job board.
  • Website basics: title, meta description, language, HTTP security headers and an optional security.txt check.

By signalscouter.

Who it's for

  • Sales and RevOps: filter accounts by technology (for example "uses Shopify and Klaviyo", or "on HubSpot, not Salesforce"), and prioritise companies that are hiring.
  • Agencies and SaaS vendors: find prospects on a competitor's or partner's platform.
  • Security and deliverability teams: audit SPF, DMARC and DKIM posture across a portfolio of domains.
  • Investors and analysts: monitor a list of companies for stack changes and hiring momentum over time.

Input

The minimum input is a list of domains. URLs and email addresses are accepted too; they are normalised to the registrable domain using the Public Suffix List (https://www.shop.example.co.uk/x becomes example.co.uk, and jane@acme.com becomes acme.com).

Duplicates are merged by registrable domain. example.co.uk, shop.example.co.uk and jane@example.co.uk produce one row, analysed and charged once. The row's inputs field lists every original input that was merged into it, and input holds the first one. The analysis is of the registrable domain's own website: if one of your inputs is the domain itself or its www host, that page (path included) is used, otherwise the homepage https://<domain>/. A subdomain such as jobs.stripe.com therefore gives you the stripe.com row rather than a separate one. Sites on shared platforms listed in the Public Suffix List, such as acme.myshopify.com or foo.github.io, count as their own domains, so different shops stay separate (their RDAP lookupStatus is platform_subdomain, because the registration belongs to the platform). RUN_SUMMARY.duplicateInputsMerged tells you how many inputs were merged.

{
"domains": ["webflow.com", "allbirds.com", "monzo.com", "https://www.pret.co.uk/en-GB"],
"checks": ["tech", "dns", "emailSecurity", "rdap", "ats"],
"technologyFilter": [],
"onlyChanges": false
}
FieldDefaultWhat it does
domainsDomains, URLs or emails.
datasetId / datasetFielddomainReads domains from another dataset, for example the output of a lead-list Actor.
checkstech, dns, emailSecurity, rdap, atsTurn off what you don't need to make runs faster. securityTxt is optional.
pagesPerDomain1Number of pages to fetch (1–5). Values above 1 add a few linked first-party pages, such as pricing or contact, which catches more tools.
atsProbeSlugstrueIf the site doesn't link to its job board, checks whether boards.greenhouse.io/<name> or jobs.ashbyhq.com/<name> exists. A match is accepted only when the site has a careers page and the board name matches the site title.
technologyFilter / categoryFilterOutput only domains that match, for example ["Shopify"] or ["chat"]. Filtered-out domains are not charged.
onlyChangesfalseMonitoring mode. It compares each domain with the previous run (stored in the named key-value store company-tech-signals-state) and outputs only domains that changed, with added, removed and changedFields. Unchanged domains are not charged.
maxDomains0 (all)A cap for testing. Applied after duplicates are merged.
maxConcurrency10Number of domains processed in parallel.
requestTimeoutSecs15Timeout per HTTP request.
perHostDelaySecs0.5Minimum gap between requests to the same host. A larger robots.txt Crawl-delay (up to 10 s) takes priority.

Output

There is one dataset row per domain. A shortened real row from a test run (October 2026):

{
"recordType": "domain",
"domain": "webflow.com",
"finalUrl": "https://webflow.com/",
"httpStatus": 200,
"title": "Webflow: The agentic web platform for modern businesses",
"language": "en",
"technologies": [
{"name": "Webflow", "category": "cms", "confidence": 100, "evidence": "meta generator: Webflow; asset https://cdn.prod.website-files.com"},
{"name": "Marketo", "category": "marketingAutomation", "confidence": 90, "evidence": "asset //go.webflow.com/js/forms2/js/forms2.min.js"},
{"name": "Intellimize", "category": "abTesting", "confidence": 90, "evidence": "asset https://cdn.intellimize.co/snippet/…js"},
{"name": "Google Tag Manager", "category": "tagManager", "confidence": 90, "evidence": "asset https://www.googletagmanager.com/ns.html?id=GTM-…"}
],
"technologyCount": 14,
"cms": "Webflow",
"cdn": "Cloudflare",
"hosting": "Amazon Web Services",
"hostingSource": "ipAsn",
"marketingAutomation": ["Marketo"],
"httpSecurity": {"hsts": true, "csp": true, "xFrameOptions": true, "score": 4},
"ats": {"platform": "ashby", "boardUrl": "https://jobs.ashbyhq.com/webflow", "openJobs": 17, "detectedVia": "careersLink"},
"dns": {
"dnsProvider": "Amazon Route 53",
"mxProvider": "Google Workspace",
"txtVerifications": ["Atlassian", "HubSpot", "Miro", "OpenAI", "Stripe", "…"]
},
"emailSecurity": {
"spfPolicy": "neutral (?all)",
"spfServices": ["Google Workspace", "Mailjet", "Zendesk", "Salesforce", "Mailgun"],
"dmarcPolicy": "reject",
"dmarcVendors": ["Red Sift OnDMARC"],
"dkimFound": true,
"grade": "B"
},
"rdap": {"registrar": "MarkMonitor Inc.", "createdAt": "2003-03-31T19:16:33+00:00", "ageYears": 23.6, "dnssec": false, "lookupStatus": "ok"},
"partial": false,
"checkErrors": null,
"durationSecs": 7.0
}

Flat columns (cms, ecommerce, analytics, chat, payments and so on) make spreadsheet filtering easy. The full list is in the Overview and Technologies views of the dataset. Other views cover Email security, Domain and hiring, Changes (monitoring mode) and Errors.

Errors get their own row (recordType: "error", with an error code such as INVALID_DOMAIN or DOMAIN_NOT_FOUND) and are never charged. If one check fails but others work (for example, the website blocks bots but DNS and RDAP succeed), the row is still delivered with partial: true, and checkErrors says what failed, such as {"web": "HTTP_403"}.

A RUN_SUMMARY record in the default key-value store reports success rate, timings, request counts and how many domains were filtered, unchanged or stopped at your spending limit.

Email-security grade

GradeMeaning
ASPF -all/~all, DMARC reject/quarantine at 100%, and DKIM found
BDMARC enforced, with either strict SPF or DKIM
CSPF and DMARC published, but DMARC not enforced (p=none) or only weakly backed
DOnly SPF or only DMARC
FNeither

DKIM is checked only on 16 common selectors, so "DKIM not found" does not prove DKIM is missing.

Pricing

Pay per event: $2.00 per 1,000 domains. Each successful domain row is one domain-analyzed event at $0.002.

You pay only for delivered domain rows. These are not charged:

  • error rows (invalid or nonexistent domains)
  • domains removed by your technology or category filters
  • unchanged domains in monitoring mode

There is no separate charge per run start or per dataset item.

The Actor respects your maximum spending limit and stops when it is reached. Every domain that was not delivered because of the limit is counted in RUN_SUMMARY.droppedAtChargeLimit: both domains that were in progress when the limit was hit and domains that never started. RUN_SUMMARY also reports chargeableResults, charged and errorRowsNotCharged, so you can check every bill.

Performance

In local tests on 46 real, varied domains (SaaS, e-commerce, media, UK retail, government, non-profits):

  • 100% of real domains returned a row; 85% (39 of 46) had full website analysis.
  • The rest were blocked by bot protection or unreachable over HTTPS. Those rows still have DNS, email and RDAP data, and are marked partial.
  • Median time was about 6 s per domain (most of it is deliberate politeness delay). With the default concurrency of 10, 25 domains finish in about 17–21 s.
  • A domain behind an aggressive bot wall can take up to about 20–60 s before timing out. Each domain has a hard time limit, so the run never hangs.

Run time, memory and timeout for large lists

Throughput on the Apify platform was measured on a 152-domain list at the default concurrency of 10 (October 2026). The Actor is CPU-bound, and Apify gives a run CPU in proportion to its memory, so memory sets the speed:

MemoryTime per domain1,000 domainsDomains per hour
4 GB (default)~0.9 s~15 min~3,500–4,000
1 GB~2.5 s~45 min~1,400
512 MB~5 s~1.5 h~700

Platform usage per domain was the same at every memory size (about $0.15 per 1,000 domains), so the default is the fast one. Memory is capped at 4 GB because the Actor can't use more than one CPU core, so more memory would only cost more.

Timeout: the default run timeout is 4 hours, which fits about 14,000 domains at 4 GB. One hour handles roughly 3,500 domains, so lists of roughly 3,500+ domains need a timeout longer than 1 hour. Keep that in mind if you or an integration set a 1-hour timeout. Rule of thumb: timeout (seconds) ≈ number of domains × 1 at 4 GB (× 3 at 1 GB, × 6 at 512 MB) + 120. If a run times out, rows already delivered are kept (and charged); split very long lists into several runs.

Limitations (please read)

  • No JavaScript rendering. Detection uses the HTML, headers, cookies and URLs that are visible in the page source. Tools loaded later by a tag manager or bundled into app JavaScript can be missed. For example, a site might load its analytics only through Google Tag Manager. Expect solid coverage of CMS, e-commerce, CDN, hosting, frameworks and most marketing tags, and lower coverage of tags loaded inside GTM.
  • Bot-protected sites (some large retail, travel and fintech sites) return 403 or a challenge page. Those rows have header-level detection only, plus DNS, email and RDAP, and are marked blockedByBotProtection: true.
  • RDAP is unavailable for some TLDs, for example .de, .io and .so, where lookupStatus is unsupported_tld. Registrars also differ in which dates they publish.
  • Inline-URL detections (confidence 80) come from URLs found inside inline scripts. They can occasionally come from allowlists or embed code rather than an active tool.
  • ATS: open-job counts are available for Greenhouse, Lever, Ashby, Workable, Workday, BambooHR, Recruitee, Teamtailor, Personio, Breezy, Pinpoint and Rippling. The other 23 ATSes (iCIMS, SmartRecruiters, SuccessFactors, Taleo and others) are detected but not counted. Lever is found only when the site links to it. Slug guessing is deliberately conservative, so some companies' boards are missed rather than misattributed.
  • Fingerprints are signalscouter's own, written and maintained by hand. Niche tools may be missing. Request them in the Issues tab.
  • Public data only. The Actor reads public website pages, public DNS records (over DNS-over-HTTPS), public RDAP registry data and public ATS job-board APIs. It uses no logins and no paid or private data sources, and it doesn't bypass bot protection.
  • robots.txt is respected on every host, including each redirect hop, and Crawl-delay is honoured. Requests are rate-limited per host and identified with the user-agent signalscouterBot/1.0.
  • No personal data. The Actor doesn't output registrant contacts (including RDAP contact data), names, emails or phone numbers. DMARC report addresses are reduced to their domain, and security.txt reports contact types only.
  • You are responsible for using the results in line with the law and the terms of the sites you analyse.

More signalscouter Actors

ActorWhat it gives you
Career Site Jobs ScraperJobs from 12 ATSes (Greenhouse, Lever, Ashby, Workday, Workable and more) in one schema, from company domains
Workday Jobs ScraperJobs from any myworkdayjobs.com career site, including sites with more than 2,000 jobs
UK Public Sector Jobs ScraperNHS Jobs, Teaching Vacancies and DWP Find a Job
SEC Form D Funding SignalsNewly funded US companies from SEC Form D filings

Support and contact

For bugs or fingerprint requests, use the Issues tab on this Actor's page. For anything else, email signalscouter.data@gmail.com.

Changelog

  • 0.2: inputs are de-duplicated by registrable domain (Public Suffix List), with all original inputs kept in inputs. Platform subdomains such as acme.myshopify.com stay separate. droppedAtChargeLimit now also counts domains that never started. The default timeout is now 4 hours, with memory capped at 4 GB. Monitoring state is keyed on the registrable domain.
  • 0.1: first version.