Company Firmographics Scraper
Enrich a domain or company name with exact employee count, revenue, HQ address, industry, founding year, ownership and ticker. No API key and no login needed.
How it works
- 1Open it on Apify
Hit Run on Apify — it opens the tool in the cloud, no install.
- 2Set the inputs
Adjust
companyDomains,companyNames,companyUrls(sensible defaults are pre-filled). - 3Click Run
The tool runs on Apify’s cloud and collects the data for you.
- 4Export the results
Download as JSON, CSV or Excel, or pipe straight into your app, Google Sheets, or an AI agent.
Pricing
$0.00092 per company = $0.92 per 1,000
| You are charged for | When | Price |
|---|---|---|
| Company returned | One company with its revenue, employee count, address, industry, founding year and ticker. A company that cannot be resolved returns an uncharged row instead. | $0.00092 |
Pay-per-event pricing: you are billed per result, not per subscription. Billing is handled by Apify on your own account. These are the live Apify store prices, in effect since 2026-09-20, and they are what you are actually charged.
Inputs
| Field | What it does | Type |
|---|---|---|
companyDomains | The company's own website domain, such as stripe.com or deliveroo.co.uk. This is the most reliable way to ask, because the domain is what the returned record is checked against - a profile whose website does not match yours is never charged for. Scheme and www. are stripped for you. | array |
companyNames | Company names, such as Cloudflare or Trader Joe's. Less precise than a domain: several companies share a name, so a name-only lookup is only returned when the name on the profile matches yours after its legal suffix is stripped. If you have both, put the names and the domains in the same order and each pair is treated as one company. | array |
companyUrls | Links of the form https://www.owler.com/company/shopify. Use these when you already know which profile you want, or when a name or domain lookup came back saying it was not confident. A link is taken at face value and always returned if the page exists. | array |
maxResults | A ceiling on how many companies are returned, whatever you put in the lists above. Hard limit 1,000. Keep it low while you are testing - you pay per company returned. | integer |
proxyUrls | Optional, and a normal run does not need it. If you add servers of your own, written as http://user:pass@host:port, the run sends some of its requests through them, not necessarily all. | array |
What you get
A structured dataset — each result includes fields like:
companyNamewebsiteindustrySectorsemployeeCountrevenueUsdfoundedYearownershipstatustickerexchangecitystatecountryowlerUrlExport every run as JSON, CSV or Excel, or send it to your app, a database, Google Sheets, or an AI agent.
Related tools in Developer & Research Tools
Other ready-to-run tools in the same category — all pay-per-use on the Apify cloud.
GitHub Scraper
Search GitHub repos and users: stars, forks, language, topics, licence, plus user bio, company and followers. No token needed. $0.90 per 1,000 rows.
Stack Overflow / Stack Exchange Scraper
Search Stack Overflow and Stack Exchange by keyword or tag. Score, answer count, views, reputation and body text. $2 per 1,000 questions.
Package Registry Scraper (npm + PyPI)
Get npm and PyPI package metadata as JSON. Version, license, author, repo, keywords and npm monthly downloads. $2 per 1,000 packages.
arXiv Scraper
Search arXiv papers by title, author, abstract or category. Get full abstracts, authors, categories, DOI, dates and PDF links. $2 per 1,000 papers.
OpenAlex Scholarly Works Scraper
Search 250M+ OpenAlex papers with no API key. Get titles, authors, venue, year, citations, DOI, OA links and full abstracts. $2.00 per 1,000 papers.
Crossref Scholarly Works Scraper
Search 150M+ papers on Crossref: DOI, title, authors, journal, publisher, date, citations and abstract. No API key. $1.00 per 1,000 works.
Where this tool sits
- Categories
- Developer & Research Tools
Company Firmographics Scraper: revenue, headcount, address and ownership from a company domain
Give it a company's domain, its name or its profile link, and it returns one row per company: the legal name, website, street address, industry, exact employee count, revenue in dollars, founding year, ownership and ticker. Every row is checked against the company you asked for, and a profile that does not match comes back as a free note naming what was found, never billed as your answer. About one lookup in ten finds no company it can confirm, and on a private company the revenue is the source's own estimate, not a filing.
| Input | Company domains, company names, or company profile links |
| Output | One row per company |
| Ceiling | 1,000 companies per run |
| Account needed | None |
| Price | $0.92 per 1,000 companies, flat on every plan |
🔍 What Company Firmographics Scraper does
It reads the company's public profile and takes the structured record the page is built from, not the rendered text. That is why employee count and revenue come back as exact integers, 7,600 staff and $13,269,000,000 rather than "1,001-5,000" and "$10B+", and why a figure the source never published comes back null rather than as a guess.
The matching is strict on purpose. A domain lookup is returned only when the website on the profile is exactly that domain, so it cannot hand you a namesake. A name-only lookup is returned when the name on the profile matches yours once the legal suffix is stripped, and those rows say matchedOn: "name", because nothing then confirms it is your company. A profile link you paste is taken at face value.
Measured on 50 real domain lookups: 45 returned a company and 5 did not. All five misses were profiles filed under a different website than the one asked for, so they were refused rather than guessed at. Well-known companies land more often: 24 of 25 on the first batch, 21 of 25 on a deliberately obscure second one.
A company that has been bought reports status: "Acquired" and names its parent and the month. The profile also carries named executives with photos and their LinkedIn links, plus a switchboard number. None of that is emitted.
📥 What you give it
{
"companyDomains": ["stripe.com", "deliveroo.co.uk", "octopus.energy"],
"maxResults": 25
}
With no company in the input, the run writes one free sample row and stops.
| Field | When left out | What it is |
|---|---|---|
companyDomains | none | The company's own website domain, such as stripe.com or deliveroo.co.uk. The most reliable way to ask. Scheme and www. are stripped for you. |
companyNames | none | Company names, such as Cloudflare. Looser than a domain. Give names and domains as two lists of the same length and each pair counts as one company. |
companyUrls | none | Profile links of the form https://www.owler.com/company/shopify, taken at face value and returned if the page exists. |
maxResults | 10 | 1 to 1,000 companies returned, whatever the lists hold. Keep it low while testing. |
proxyUrls | not needed | Optional. Servers of your own to send the requests through, as http://user:pass@host:port. |
📤 What you get back
A real row from a run on 30 September 2026:
{
"ok": true,
"charged": true,
"recordType": "company",
"companyName": "Stripe, Inc.",
"shortName": "Stripe",
"website": "https://stripe.com/",
"domain": "stripe.com",
"description": "Stripe is a California-based financial infrastructure platform that offers solutions such as payment processing, VAT automation and invoice management for businesses.",
"industrySectors": ["Fintech Software"],
"industryGroups": ["Banking, Financial Services and Insurance"],
"employeeCount": 8200,
"revenueUsd": 5100000000,
"foundedYear": 2009,
"ownership": "Private",
"status": "Independent Company",
"parentCompany": null,
"acquiredOn": null,
"ticker": null,
"exchange": null,
"street1": "185 Berry Street",
"street2": "Suite 550",
"city": "San Francisco",
"state": "California",
"country": "USA",
"postcode": "94107",
"owlerUrl": "https://www.owler.com/company/stripe",
"companyId": "100441",
"profileCompleteness": 100,
"matchedOn": "domain",
"requestedName": null,
"requestedDomain": "stripe.com",
"scrapedAt": "2026-09-30T02:25:05.027Z"
}
| Field | What it is |
|---|---|
ok, charged, recordType | true, true and company on every company row. |
companyName, shortName | The legal entity, which is often not the brand (Airtable comes back as Formagrid, Inc.), and the brand. |
website, domain, description | As the profile gives them. |
industrySectors, industryGroups | The specific sector, and the broad group above it. Thin profiles often have the group and not the sector. |
employeeCount, revenueUsd, foundedYear | Exact integers, or null when not published. Never written as 0. |
ownership, status, parentCompany, acquiredOn | Public or private, and Independent Company or Acquired. Deliveroo PLC, for one, reports Acquired, DoorDash, Inc. and 05/2025. |
ticker, exchange | Listed companies only. Null on a private one. |
street1, street2, city, state, country, postcode | The full postal address. country is published as found, so CA, GB and USA sit side by side. USA is the only three-letter code seen so far. |
owlerUrl, companyId | The profile link and its id. |
profileCompleteness | The source's own 0 to 100 fill rate for the record. 100 is a full profile, 25 a stub with a name and a city. |
matchedOn | domain when the profile's website is exactly your domain, the strongest; name when the name was the only evidence; url when you gave the link. |
requestedName, requestedDomain, scrapedAt | What you asked for, so you can join the rows back onto your list, and when it was read. |
🧾 Reading the output
| Row | How to spot it | Charged |
|---|---|---|
| A company | recordType: "company" and charged: true | yes |
| The sample row | _sample: true, recordType: "sample", charged: false. Only when the input has no company in it | no |
| A note | _diagnostic: true, recordType: "diagnostic", charged: false, and an errorCode | no |
charged is what separates company rows from the free ones. To keep only companies, filter on recordType equal to company.
errorCode | What it means |
|---|---|
NO_RESULTS | A profile was found but did not match the company you asked for, and the note names what it found. It is also used when a company was already returned earlier in the run. |
NOT_FOUND | No profile exists for that company. |
BLOCKED | The profile could not be read in this run. Worth one re-run. |
BAD_INPUT | An entry could not be turned into a lookup. |
TIME_BUDGET | The run stopped before it reached that company, so it was never looked up. Try again, or run fewer at once. |
The pair to tell apart is NO_RESULTS and BLOCKED. The first means the company could not be confirmed, the second means nobody got to look.
▶️ How to run it
1. Open Company Firmographics Scraper and click Try for free. 2. Paste domains into Company domains, one per line. 3. If you only have names, use Company names, or both lists in the same order. 4. Set Maximum companies to return. 5. Click Start, then download the dataset as JSON, CSV or Excel.
The form arrives with stripe.com, shopify.com and 10 already filled in, so a run started without editing it is two real lookups.
💰 How much does it cost?
$0.92 per 1,000 companies returned, flat on every Apify plan, with no volume tiers.
You pay only for companies that come back with data. A miss, a mismatch, a note and the sample row are free, and a company reached twice in one run, once by name and once by domain, is charged once.
💡 What people use it for
- Filling in the size, revenue and location columns on a CRM export that arrived as nothing but names and domains.
- Scoring inbound sign-ups by company size before a person looks at them.
- Checking whether a supplier still stands on its own, since an acquired company names its parent.
- Account planning where a real headcount matters more than a band.
🚧 What it does not do
- It does not find every company. About one lookup in ten comes back as a free note instead. When the miss is a
profile filed under another website, the note names that company and its website, so you can check it and pass its profile link in companyUrls if it is the right one.
- A name on its own can still match a namesake. Those rows say
matchedOn: "name". If you have the domain, use it. - Revenue is not a filing. For public companies it tracks reported figures closely; for private ones it is the
source's model. Treat it as a size band that happens to be written as a precise number.
- Blanks are the source's blanks. Small and very new companies often have almost nothing on their profile, and the
figures are refreshed from time to time, not live.
- No people. No executives, photos, LinkedIn links or phone numbers.
- No funding rounds, investors, news, competitors or employee reviews. One company, one row of firmographics.
- No discovery. You bring the list and it fills in the columns. There is no "every fintech in Berlin" search.
🧭 Which company data scraper do you need?
| If you want | Use |
|---|---|
| A company's size, revenue, address and ownership from its domain | This one |
| A company's LinkedIn page: followers, employee count and headquarters | LinkedIn Companies Scraper |
| European register records: legal form, register number and status | North Data Scraper |
| Every company Companies House registered on the days you pick | New UK Companies Scraper |
| Emails, phone numbers and social profiles from a list of websites | Contact Details Scraper |
| A website's traffic, rank and audience geography | Similarweb Traffic and Rank Scraper |
❓ Questions people ask
Do I need an account or an API key for anything? No. There is no login, no cookie and no key, and you do not need an account with the source.
Why is revenue null on a company I know makes money? The source has not published a figure for it, which is common for private companies. It is never written as 0, so a blank and a zero never look the same.
I asked for a domain and got a note saying it was not confident. What now? A profile was found under a different website from the one you gave, and the note names that company and its website. If it is the company you meant, put its profile link in companyUrls.
Is the employee count exact or a band? An exact integer, when the source publishes one.
What happens on a company that has been acquired? status reads Acquired and the parent and month are filled in. The rest of the row still describes the company you asked about, not its parent.
Can I run this on a schedule? Yes. Nothing is held between runs, and requestedDomain is a stable key for joining today's rows onto yesterday's.
🆘 If something breaks
Open the Issues tab on the actor page. Send the input you used and the run ID, and the errorCode and details on any note.