sfoln/company-enrichment · Lead generation, Developer tools, Automation On request
Enrich a company domain into one live profile: name, legal name, logo, addresses, emails, phones, socials, tech stack, MX/SPF/DMARC, domain age, open jobs, LEI and SEC ticker, Shopify flag. Optional name lookup and LinkedIn data. $5 per 1,000 companies.
Turn a company domain into one live company profile: the Actor reads the company's own website (homepage plus up to three contact, imprint, careers and about pages), its DNS records, its domain registration and TLS certificate, its public job board and the free LEI and SEC registers, and returns about 60 normalized fields in one JSON record: name and legal name, logo, addresses, e-mails (locally pre-checked), phones (E.164), social profiles, tech stack, SaaS tools seen in DNS, mail provider with SPF and DMARC, domain age, SSL, open jobs by department, LEI, SEC CIK and ticker, VAT and register numbers, and a Shopify / WooCommerce store flag. Built for SDR and RevOps teams enriching CRM accounts, VC and M&A screening, and AI agents answering "tell me about acme.com". Nothing comes from a stale database: every profile is read live.
Price
Price per delivered record
Event
Price
Per 1,000
Charged for
Company profile company-profile
$0.005
$5 / 1,000
Charged once per company whose website was read: one profile with names, logo, addresses, e-mails (pre-checked), phones, socials, tech stack, e-mail DNS setup, domain age, SSL, hiring snapshot, LEI / SEC identifiers and store flags.
LinkedIn company profile linkedin-firmographics paid plans only
$0.007
$7 / 1,000
Paid add-on (includeLinkedIn): the company's LinkedIn page linked from its website (industry, size, employees on LinkedIn, followers, headquarters, founded, specialties, funding). Paid Apify plans only.
Company name lookup company-name-lookup paid plans only
$0.0045
$4.5 / 1,000
Paid add-on (companyNames): one Google search for a company name to find its website (knowledge graph and organic results, verified against the site's own name). Paid Apify plans only.
Apify free plan: up to 10 items per run. Paid plans have no per-run cap; set maxTotalChargeUsd to cap spend.
Run
Call it from code, an agent or the Console
This API is private on Apify for now. Email us and we will publish it for you, usually within two working days. The calls below work once it is public. contact@sfoln.com
POST https://api.apify.com/v2/actors/sfoln~company-enrichment/runs?maxTotalChargeUsd=1
GET https://api.apify.com/v2/actor-runs/{runId} # until status is SUCCEEDED
GET https://api.apify.com/v2/datasets/{defaultDatasetId}/items?format=json
Authenticate with an Apify API token. MCP clients can instead sign in with OAuth when prompted. Example prompt for an agent: Enrich apify.com: give me the company's legal name, address, LinkedIn page, tech stack, e-mail provider, number of open jobs and its LEI.
Input
Input fields
Enter company domains (or, on paid plans, company names). Each company produces one profile record.
Field
Type
Default
Meaning
domains
array
—
Company domains Company websites as domains (apify.com) or URLs, one per line. Duplicates are removed. Accounts on the Apify free plan can process up to 10 companies per run.
companyNames
array
[]
Company names (paid plans) Company names to find the website of first, one per line, optionally with a country: "Acme Widgets | DE". Each name costs one search ($0.0045, company-name-lookup) whether or not a website is found; the profile is charged only when the website was found. Paid Apify plans only.
country
string
—
Default country for names ISO country code (US, DE) used for company names given without one: it localises the search.
includeLinkedIn
boolean
false
LinkedIn company data Also read the company's LinkedIn page linked from its website (industry, size, employees, followers, funding). Paid add-on: $0.007 per company (linkedin-firmographics), paid Apify plans only.
includeHiring
boolean
true
Hiring snapshot Find the company's job board (Greenhouse, Lever, Ashby, Workable, Recruitee, Personio, Teamtailor, SmartRecruiters, BambooHR, Breezy, Workday) and count its open roles by department.
guessJobBoard
boolean
true
Guess the job board from the domain When the website links no job board, try the domain name on the main ATS APIs (the match is checked against the company; reported as detectedBy slug_guess).
includeIdentifiers
boolean
true
LEI and SEC identifiers Look the company up in GLEIF (LEI) and SEC EDGAR (CIK, ticker, exchange).
maxPages
integer
4
Pages per website Pages read per company: the homepage plus up to 3 of its contact, imprint, careers and about pages. Range 1–4.
maxItems
integer
1000
Max companies Safety cap on how many companies (domains and names) are processed in this run. Range 1–10000.
concurrency
integer
5
Concurrency How many companies are enriched in parallel (1–10). Range 1–10.
includeRaw
boolean
false
Include raw response data Attach the homepage's response headers, redirects and its JSON-LD Organization under raw.
Example input
{
"domains": [
"apify.com"
]
}
Output
One record per input item
Records land in the run's dataset; a synchronous call returns them directly. Each has a status (ok is charged; everything else is free) and a charged flag. The run's OUTPUT record totals items and charges.
Field
Type
Meaning
input
string | object
Input The domain or URL as given, or { companyName, country } for a name lookup.
status
string
Status ok | not_found | error | skipped_invalid | skipped_budget | skipped_free_plan | skipped_unmetered
charged
boolean
Charged Whether this record incurred a company-profile charge (paid add-ons charged for it are listed in chargedAddOns).
chargedEvent
string
Charged event company-profile (present only when charged).
chargedCount
integer
Events charged Events actually charged when the charge came back short (present only then).
chargedAddOns
array
Charged add-ons Paid add-on events charged for this record (company-name-lookup, linkedin-firmographics), also when the profile itself was not found or not charged; present only when one was charged.
source
string
Source Upstream data sources.
fetchedAt
string
Fetched at ISO timestamp.
error
object
Error { code, message, provider?, status? } when status is not ok: invalid_domain, domain_not_found, site_blocked, page_not_found, http_error, website_not_found, name_lookup_paid_plan, budget_exhausted, plus the runtime codes (budget_exhausted, free_plan_limit, unmetered, aborted, charge_failed, record_too_large, invalid_record, dataset_push_failed) and upstream codes (auth, insufficient_credits, rate_limit, timeout, network, server, client, invalid_response, not_found).
warnings
array
Warnings Sections that failed or were skipped, pages that could not be read, add-on notes.
inputType
string
Input type domain or company_name.
domain
string | null
Domain Registrable domain of the company (apify.com); for a site on a shared platform domain the site's own host (acme.myshopify.com), whose DNS and RDAP sections are then skipped.
website
string | null
Website Final homepage URL after redirects.
companyName
string | null
Company name Name from JSON-LD, og:site_name or the page title.
legalName
string | null
Legal name Legal name published in JSON-LD (legalName), else the registered name in the imprint or footer text.
legalNameSource
string | null
Legal name source Where legalName comes from: json-ld, imprint or website_text (null without a legal name).
alternateName
string | null
Alternate name JSON-LD alternateName.
description
string | null
Description JSON-LD description, else the meta description.
slogan
string | null
Slogan JSON-LD slogan.
logo
string | null
Logo Logo URL from JSON-LD.
favicon
string | null
Favicon Declared favicon URL.
ogImage
string | null
Share image og:image URL.
language
string | null
Language Homepage language (html lang).
country
string | null
Country ISO 3166-1 alpha-2 country of the company.
countrySource
string | null
Country source json-ld, vat_number, registration_number, input, tld, phone or lei.
foundedYear
integer | null
Founded Founding year.
foundedYearSource
string | null
Founded source json-ld or website_text.
employees
object | null
Employees { min, max } from JSON-LD numberOfEmployees.
addresses
array
Addresses { formatted, street, city, region, postalCode, country, source } from JSON-LD, <address> elements and microdata.
emails
array
Emails { email, sourcePage, isOwnDomain, verdict, settled, role, freeProvider, disposable, typoSuggestion }: addresses published on the site, own domain first, with the local pre-check verdict (no mailbox verification).
phones
array
Phones { number (E.164), valid, country, type, source } from tel: links and JSON-LD.
socials
object
Social profiles linkedin, x, facebook, instagram, youtube, tiktok, pinterest, github (null when not linked).
techStack
array
Tech stack { name, slug, categories, version, confidence, evidence, website } detected on the pages, the TLS issuer and DNS.
Sources Pages read, dns, rdap, the job board, GLEIF and EDGAR links.
sections
object
Sections State of each part: website, dns, domain, tls, hiring, lei, sec, linkedin: ok | not_found | error | skipped | timeout (dns and domain are skipped for a site on a shared platform domain).
Live from public sources at run time: the company's own website (up to 4 pages: the homepage plus its contact, imprint, careers and about pages), its DNS records (MX, SPF, DMARC, verification TXT records, CNAMEs of common subdomains), RDAP domain registration data, its TLS certificate, the public job-board APIs of applicant tracking systems (Greenhouse, Lever, Ashby and 8 more), GLEIF (LEI register) and SEC EDGAR. Nothing comes from a stored database, so a profile is as fresh as the website.
How are LEI and SEC identifiers matched?
Conservatively: an LEI published on the site wins; then a register number or a VAT number published on the site that GLEIF knows; then an exact legal name. A brand name alone matches only when exactly one active entity has that name (in the company's country when known). The SEC registrant is matched on the exact company name in EDGAR's list of listed companies, and rejected when EDGAR records a website on another domain. Each match carries matchedBy and matchScore.
Can I enrich a company name instead of a domain?
Yes, on paid plans: put names in companyNames (optionally "Name | country code"). Each name costs one search ($0.0045, company-name-lookup, charged whether or not a website is found, and listed in the record's chargedAddOns); the best candidates' homepages are compared with the name (the site's own name, its domain or Google's knowledge-graph title must match), and the profile ($0.005) is charged only when the website was confidently found and read. Passing the domain is cheaper and exact.