How to Build a Company Dossier from a Name or Domain
Turn a company name or domain into a structured dossier — tech stack, socials, contacts, firmographics, news and competitors. One keyless call, no browser.
Company research is death by a thousand tabs. To qualify one account you open the homepage, check LinkedIn, guess the tech stack, hunt for a contact email, search for recent news, and try to name a few competitors. Do that across a lead list of 500 domains and it’s a week of clicking. And if all you have is a messy list of company names from a form, you haven’t even found the websites yet. This guide covers how to collapse that whole workflow into one keyless call that returns a structured, machine-readable dossier per company.
The job is enrichment: give it stripe.com — or just "Stripe" — and get back a flat JSON record with website metadata, tech-stack fingerprints, social profiles, contact channels, SEO basics, recent news signals, competitor domains, firmographics and blog/RSS feeds. Aggregated from the company’s own public homepage plus keyless public sources. One call replaces five separate scrapers.
What’s worth extracting
The dossier is roughly 40 fields per company. Grouped by what you’d actually query on:
Identity
companyName,title,description— name, page title, and meta/OG description.logo,favicon— logo image and favicon URLs.resolvedDomain,websiteUrl— the canonical domain and final URL after redirects.languages,ogType— detected page languages and Open Graph type.
Tech stack
techStack— up to 40+ technologies detected from HTML, script/stylesheet paths and HTTP headers: Next.js, React, Vue, Angular, Svelte, WordPress, Shopify, Webflow, Wix, Cloudflare, Vercel, Netlify, Google Analytics, GTM, HubSpot, Intercom, Segment, Stripe, Sentry, Datadog, Algolia, Tailwind and more.
Socials and contacts
socials— an array of platform/URL objects (LinkedIn, X/Twitter, GitHub, Facebook, Instagram, YouTube, TikTok, Discord, Telegram) pulled from homepage links andschema.orgsameAs.linkedinUrl,twitterUrl,githubUrl,facebookUrl,instagramUrl,youtubeUrl— the same profiles flattened into direct columns for easy filtering.emails,phones— contact channels frommailto:/tel:links and text regex, with junk filtered out.
Firmographics (from JSON-LD)
foundedYear,employeesRange,industry,country,city— parsed fromschema.orgOrganization/Corporationblocks when the site publishes them.
SEO and structure
seoTitleTag,seoMetaDescription,seoHeadings— title, meta description and H1/H2 headings.sitemapUrls,robotsTxt— sitemaps discovered fromrobots.txt.rssFeeds,blogUrl— feed URLs fromlink rel=alternatetags and common feed-path guesses.
Signals
news— recent items (last ~30 days) via Google News RSS, each with title, URL, publish date and source.competitors— alternative/competitor domains mined from public search results, with junk domains filtered.httpsValid,redirectChain,scrapedAt— HTTPS validity, the redirect path, and an ISO capture timestamp.
How the source actually works
The design choice that makes this fast and cheap: it’s direct HTTP plus lightweight HTML parsing on a small Node 20 container — no headless browser. There’s no Playwright instance to keep warm and no GraphQL token to manage. Each company is fetched, parsed and enriched in parallel.
The behavior is driven by a required mode, and the output schema is identical across all three:
domain— batch enrich a list of domains you already have. Fastest, up to 500 per run.name— resolve free-text company names to a website first (via public search and favicon lookup), then enrich. This is the one for messy CRM or form data.single— one company, maximum depth, all sections.
A high-volume batch by domain:
{
"mode": "domain",
"domains": ["stripe.com", "linear.app", "figma.com", "notion.so", "vercel.com"],
"sections": ["meta", "techStack", "socials", "contacts", "seo"],
"concurrency": 5,
"useApifyProxy": true
}
Resolving names to dossiers, the messy-lead-list case:
{
"mode": "name",
"companyNames": ["Notion", "Figma", "Linear", "Vercel", "Supabase"],
"sections": ["meta", "techStack", "socials", "contacts", "news", "competitors"],
"concurrency": 4
}
The sections field is your cost and speed lever — the eight sections are meta, techStack, socials, contacts, seo, news, competitors, rss. Trim it to only what you need; fewer sections means faster and cheaper per company. maxNews (0–50) and maxCompetitors (0–30) cap those two enrichments, and concurrency (1–20) controls parallelism — lower it for fragile targets.
▶ Run the Company Deep Research Scraper on Apify — a name or domain in, a ~40-field dossier out. No API key, no login, no browser. Export to JSON, CSV or Excel, or call it live via MCP.
The access reality
The honest picture: this reads only keyless public endpoints — a company’s own homepage over HTTP, public search for name-to-domain resolution, and Google News RSS. No authentication, no access-control bypass, no scraping behind logins. You need an Apify account and nothing else.
Where naive approaches struggle is coverage, not blocking. Homepages rarely wall you off, but a few realities shape the output:
- Firmographics depend on the site publishing JSON-LD.
foundedYear,employeesRangeandindustrycome fromschema.orgOrganizationblocks. Companies that don’t emit that markup simply won’t have those fields — the dossier is still produced with everything else. - Tech-stack detection is client-side. The fingerprint library reads script paths, framework markers and headers, so it’s reliable for the common 40+ technologies but blind to server-only tech (databases, backend languages) and deeply bundled apps. It’s vendor reconnaissance and quick triage, not exhaustive Wappalyzer-grade detection.
- Bot-walled targets degrade gracefully. If a homepage returns 403/503, the dossier is still emitted with whatever could be collected and the domain recorded — it doesn’t crash the batch. For systematically walled sites, set
proxyGroupsto["RESIDENTIAL"]; datacenter proxy is the default and fine for most.
One thing it deliberately does not do: hunt for individual employees’ personal emails. It collects contact emails published on the homepage — support, info, press — not person-level addresses. That’s a job for a dedicated person-email tool.
Example output
A trimmed dossier for one company:
{
"input": "stripe.com",
"resolvedDomain": "stripe.com",
"websiteUrl": "https://stripe.com/",
"companyName": "Stripe",
"techStack": ["Next.js", "React", "Cloudflare", "Stripe", "Google Analytics", "Segment", "Sentry"],
"socials": [
{ "platform": "twitter", "url": "https://twitter.com/stripe" },
{ "platform": "linkedin", "url": "https://www.linkedin.com/company/stripe" }
],
"emails": ["[email protected]"],
"employeesRange": "5001-10000",
"foundedYear": 2010,
"industry": "Fintech",
"country": "US",
"city": "South San Francisco",
"competitors": ["paypal.com", "adyen.com", "square.com"],
"rssFeeds": ["https://stripe.com/blog/feed"],
"httpsValid": true,
"scrapedAt": "2026-07-06T12:00:00.000Z"
}
Use cases
- CRM and lead enrichment — feed a column of domains or names and append industry, employee range, tech stack, LinkedIn and contact channels to each lead.
- AI-agent grounding (RAG) — give agents current, structured company facts instead of stale training-set knowledge; embed each dossier into a vector DB.
- Sales and account research — qualify accounts by stack, size and news momentum, then build a competitor set before outreach.
- Market mapping — assemble a landscape of hundreds of companies in a niche and cluster, filter and rank them as structured rows.
- Vendor and tool evaluation — compare candidate SaaS vendors by website, tech stack, docs and recent news in one pass.
- Competitive and news monitoring — schedule recurring runs over a watchlist and diff the datasets to track tech, news and competitor movement over time.
Cost and effort math
Building this in-house means writing and maintaining a name-to-domain resolver, a 40-signal tech-stack fingerprinter, a schema.org JSON-LD parser, an email/phone extractor with junk filtering, a Google News RSS reader, and a competitor miner over search results — six subsystems, each with its own edge cases and its own decay curve as sites change. That’s not an afternoon; it’s a maintained internal service.
The managed scraper is pay-per-result: one result event per company dossier, no separate platform fees to calculate, and runs that yield zero companies (bad input, blocked target) are not billed. Concurrency is capped at 20 to stay polite, domain mode takes batches up to 500, and a few hundred companies per run is comfortable. Trimming sections to only what you need pulls the per-company cost down directly. For enriching a lead list, you’re paying fractions of a cent per company with no proxy bill and no six-subsystem maintenance burden.
Common pitfalls
- Not every field is present on every company.
foundedYear,employeesRangeandindustryonly appear when the site publishes JSON-LD; treat missing firmographics as absent-at-source, not an error, and design your schema to allow nulls. socialsarray vs flattened columns. The same profile shows up both in thesocialsarray and as a flatlinkedinUrl/twitterUrlfield. Pick one representation for downstream joins so you don’t double-count.- Tech stack misses the backend. Don’t infer “no database” or “no backend language” from
techStack— client-side fingerprinting can’t see server-only tech. - News is a rolling ~30-day window. The
newsarray reflects recent coverage, not history. For a longer timeline, schedule recurring runs and accumulate. - Name resolution can misfire on ambiguous names. A generic company name may resolve to the wrong site. Always check
resolvedDomainagainst expectation before trusting the rest of the dossier innamemode; usedomainmode when you already have the URL. emailsare org-level only. Expect support/info/press addresses, not the specific person you’re trying to reach.
Wrapping up
Company enrichment is a lot of small scrapers wearing a trench coat. You can build each piece yourself, but the maintenance across all six is where the time goes. If you need to enrich a lead list, ground an agent, or map a market, a keyless, browser-free tool that returns one flat ~40-field dossier per company — batchable to 500, priced per result — is the piece worth buying.
▶ Open the Company Deep Research Scraper on Apify — name or domain to structured dossier: tech stack, socials, contacts, firmographics, news and competitors. Keyless, no browser, pay per company. Start on Apify’s free monthly credit.
Related guides
How to Build a Deep-Research Retrieval Layer for AI Agents
Give an agent a topic and get ranked web sources, full-page Markdown, and recent news with citations — keyless multi-source retrieval for RAG and grounding.
How to Extract Structured Data from Any URL in 2026
Turn any web page into clean JSON without an LLM: parse schema.org JSON-LD, OpenGraph, tables, prices and contacts deterministically — no API key, no browser.
How to Add Live Web Search to AI Agents (No API Key)
Give your LLM fresh, citable search results without a Tavily or SerpAPI key. How live SERP extraction works: ranked results plus Markdown page content for RAG.