Company Enrichment API – Domain to Emails, Socials & Tech
Pricing
from $0.85 / 1,000 result delivereds
Company Enrichment API – Domain to Emails, Socials & Tech
Company enrichment by domain: paste domains, website URLs or email addresses and get one record per company with what its site says it is, role email addresses, social profiles, WhatsApp, contact page and tech stack. For lead generation and CRM enrichment.
Pricing
from $0.85 / 1,000 result delivereds
Rating
0.0
(0)
Developer
Locomint
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
This company enrichment actor turns a list of domains, website URLs or email addresses into one row per company: the role email addresses, social profiles, WhatsApp number, contact page and tech stack that the company's own website publishes, with the site's title, description and language. It is domain enrichment from the source, read live during your run.
What it does
Each entry is first reduced to one host. example.com, www.example.com,
https://example.com/pricing and sales@example.com all become example.com, duplicates are
removed in the order given, and internationalised names are converted to ASCII (münchen.de
becomes xn--mnchen-3ya.de). A column of contact emails exported from a CRM therefore
collapses into a list of companies.
Two kinds of entry are dropped before anything is fetched, named in the run log and not charged: text that is not a domain, URL or email address, and the 92 free email providers such as gmail.com, yahoo.com and outlook.com, which belong to no company.
For every remaining domain the actor:
- reads the site's robots.txt and checks the homepage against the rules for all crawlers (the
*group). A disallowed homepage is not fetched; - fetches
https://<domain>/over a direct datacenter connection, with no proxy and no browser. If the bare domain does not answer,https://www.<domain>/is tried once, unless the site answered with a 403, 429 or challenge page; - reads the site's English edition instead when the homepage declares one with
hreflang, so the title and description come back in English where the site offers it; - reads the contact page as well when the homepage shows no email address or no WhatsApp number and links to one, and merges the two. One extra page, no extra charge.
| Field | What goes in it |
|---|---|
domain | The host the entry was reduced to. |
input | What you typed, so the row can be matched back to your sheet. |
website | The address that was read: https://<domain>/, or the www. form when only that answered. |
status | ok, unreachable, parked, redirect_social or robots_disallowed (table below). |
title, description, language | The page title, its meta or Open Graph description, and the language declared in <html lang>. |
emails | Up to five role mailboxes (info@, sales@, bookings@ and the like) from the homepage and contact page together. Addresses that name a person are dropped. |
socials | The first profile link per network: Facebook, Instagram, LinkedIn, X (Twitter), YouTube and TikTok. Share buttons and personal linkedin.com/in/ profiles are removed. |
whatsapp | The number in the first WhatsApp click-to-chat link, written as + and digits. |
contact_form_url | The first link on the same site whose path contains "contact". |
tech_stack | Technologies matched by signatures in the HTML (for example /wp-content/ for WordPress, cdn.shopify.com for Shopify) and in response headers. |
crawled_at | When the site was read, in UTC. |
note | Why a row looks unusual: the robots.txt rule that stopped it, robots.txt could not be read, or no answer within the time limit. |
Every domain you send, apart from the skipped entries above, comes back as a row with a
status, so a site that failed is visible in the dataset instead of missing from it.
Who it is for
- Lead generation and sales prospecting. Turn a list of company domains from a trade-show list, a directory export or the website column of the Locomint Google Maps actors into a sheet with each company's published mailboxes, WhatsApp number and social profiles.
- CRM and spreadsheet enrichment. Export the email or website column and run it as it is.
Because
sales@example.comandhttps://example.com/aboutreduce to the same domain, contacts de-duplicate into companies; merge the results back oninputordomain. - Agencies qualifying a niche. The tech stack sits in the same row, so "Shopify stores with an Instagram profile and no published email" is a filter, not an afternoon of clicking.
- Market research. Count a segment by platform, by declared language, or by how many domains in it are parked or only redirect to a social profile.
How to use it
In the Apify Console:
- Paste domains, website URLs or email addresses into Domains, websites or email addresses, one per line, up to 5,000. Mixed formats in one list are fine.
- Leave Read the contact page too, Honour robots.txt and Skip free email providers on unless you have a reason to change them.
- Set a maximum cost per run if you want a ceiling. The actor stops before the row that would pass it.
- Start the run. The Companies view shows domain, status, title, emails, social profiles, WhatsApp, contact page and tech stack; What each site says shows what you entered, the address read, title, description, language and note. Export as CSV, Excel or JSON.
From the API, this call starts a run, waits for it and returns the rows:
curl -X POST \"https://api.apify.com/v2/acts/locomint~company-enrichment/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"domains": ["coffeecollective.dk", "https://www.monmouthcoffee.co.uk/"]}'
The synchronous endpoint waits up to 300 seconds. For a long list, start the run with
POST https://api.apify.com/v2/acts/locomint~company-enrichment/runs?token=YOUR_APIFY_TOKEN
and read its dataset when the run finishes. With the Python client (
pip install apify-clientfrom apify_client import ApifyClientclient = ApifyClient("YOUR_APIFY_TOKEN")run = client.actor("locomint/company-enrichment").call(run_input={"domains": ["coffeecollective.dk", "fassbender-rausch.de"]})for row in client.dataset(run.default_dataset_id).iterate_items():print(row["domain"], row["status"], row["emails"], row["tech_stack"])
Input example
{"domains": ["coffeecollective.dk","https://www.monmouthcoffee.co.uk/","fassbender-rausch.de"],"followContactPage": true,"respectRobots": true,"skipFreeEmailDomains": true,"concurrency": 5,"siteTimeout": 30}
| Field | Default | Allowed | What it does |
|---|---|---|---|
domains | required | 1 to 5,000 entries | Domains, URLs or email addresses. Through the API, one string with entries separated by new lines, commas or semicolons also works. Over 5,000 after de-duplication, the first 5,000 are used. |
followContactPage | true | true / false | Read the contact page when the homepage has no email or no WhatsApp number. |
respectRobots | true | true / false | Skip a site whose robots.txt disallows its homepage; the row arrives as robots_disallowed. |
skipFreeEmailDomains | true | true / false | Leave out gmail.com, yahoo.com, outlook.com and 89 similar providers, uncharged. |
concurrency | 5 | 1 to 10 | Sites read at the same time. |
siteTimeout | 30 | 5 to 90 seconds | A site with no answer by then is delivered as unreachable. |
Output example
A real row, from a run on 11 September 2026 with the input above. The four addresses are role mailboxes the company publishes (general, web shop, orders and jobs).
{"domain": "coffeecollective.dk","input": "coffeecollective.dk","website": "https://coffeecollective.dk/","status": "ok","title": "Coffee Collective","description": "A specialty coffee roastery. We work directly with farmers to ensure quality, transparency, and sustainability - creating experiences from farmer to guest.","language": "en","emails": ["mail@coffeecollective.dk","webshop@coffeecollective.dk","ordre@coffeecollective.dk","job@coffeecollective.dk"],"socials": {"instagram": "https://www.instagram.com/coffeecollectif","linkedin": "https://www.linkedin.com/company/coffeecollective"},"whatsapp": null,"contact_form_url": "https://coffeecollective.dk/policies/contact-information","tech_stack": ["shopify", "google-analytics", "google-tag-manager", "recaptcha", "cloudflare"],"crawled_at": "2026-09-11T18:42:08+00:00","note": null}
The other two rows from that run show the common variations. https://www.monmouthcoffee.co.uk/
became monmouthcoffee.co.uk, read as WordPress with WooCommerce, with an Instagram profile and
no published mailbox, so emails is empty. fassbender-rausch.de came back with service@ and
b2b@ addresses on rausch.de, the domain the company's mail actually uses, and the note
robots.txt could not be read, so no rules were applied.
Status values
status | Meaning | Fields |
|---|---|---|
ok | The homepage was read. | Whatever the site publishes; an empty list means none was found in the HTML. |
unreachable | No connection, a DNS failure, an HTTP error, a 403, 429 or challenge page, or no answer within siteTimeout. Not retried from another address. | Empty, with a note. |
parked | The homepage matches a parked-domain, for-sale or coming-soon signature. | Empty. |
redirect_social | The domain redirects to a social network profile instead of a website. | socials holds that profile. |
robots_disallowed | robots.txt disallows the homepage, so nothing was fetched. | Empty; note quotes the rule. |
Pricing
| Event | Price |
|---|---|
| Company delivered (one dataset row) | $0.001, which is $1.00 per 1,000 until 26 September 2026, then $0.005, which is $5.00 per 1,000 |
| Actor start | $0.00005 per GB of run memory, charged once per run |
Worked example: 10,000 domains is two runs of 5,000, so 10,000 x $0.001 = $10.00 plus two start events of $0.00005 each for 1 GB runs. From 26 September 2026 the price per domain becomes $0.005.
You pay only these event prices; Apify compute is not billed to you separately, and the contact
page costs nothing on top of the domain. Every row is charged, including unreachable,
parked and robots_disallowed, because each is an answer about that domain. Skipped entries
(not a domain, or a free email provider) produce no row and no charge. If you set a maximum
cost per run, the actor stops before the row that would pass it.
FAQ
Why is an email missing that I can see on the site?
Only the homepage and one contact page are read, so an address on another page is not found. Addresses inserted by JavaScript, hidden by Cloudflare's email protection, written as "info [at] example.com" or shown as an image are not decoded. Addresses that name a person are dropped on purpose, and at most five are returned per domain.
Can I send email addresses instead of domains?
Yes. sales@example.com is reduced to example.com and the row describes that company's
website. The address you sent stays in input but is not checked; to test whether addresses
accept mail, use the Bulk Email Verifier listed below.
Why did some of my entries produce no row?
Entries that are not a domain, URL or email address, and free providers such as gmail.com, are skipped before the run starts and named in the run log, uncharged. Entries past the first 5,000 unique domains are left out and counted in the log too.
Does it try the www address?
Yes, once, when the bare domain does not answer, refuses the connection or returns an error.
website shows which address was read. It never tries www. after a 403, 429 or challenge
page, because a site that has asked us to stop is not approached under its other name.
What happens when a site blocks it?
A 403, 429 or challenge page makes that domain unreachable. It is not retried from the same
address or any other, and the host is left alone for 15 minutes. The actor does not solve
CAPTCHAs or rotate IP addresses, so sites behind strict firewalls come back unreachable more
often than they would in a browser.
Does it honour robots.txt?
Yes, for the homepage. If the * group disallows it, the site is not fetched and the row is
robots_disallowed with the rule in note. A site with no robots.txt has no rules; one whose
robots.txt cannot be read is fetched anyway and note says so.
Does it return phone numbers, company size or industry?
Phone numbers only when the site has a WhatsApp click-to-chat link. Everything comes from the company's own website, so there is no headcount, revenue, industry code or founder data. The Locomint Google Maps actors return each business's listed phone number.
Limits
- No JavaScript rendering. A site built entirely in the browser returns a title and little else.
- The homepage plus at most one contact page per domain. 5,000 domains per run, 30 seconds per site by default (5 to 90), 3 MB of HTML per page, at most 5 redirects, each checked before it is followed.
- Up to five role mailboxes per domain. Cloudflare-protected, image and "[at]" addresses are not decoded.
- Social profiles: the first link per network. The actor records the link and never opens the profile.
- robots.txt is applied to the homepage. The contact page, and a site's English edition when it declares one, are read without a separate check.
websiteis the address the run started from. When a site redirects to another domain the row does not name it, though the email addresses often show it.- Datacenter connection only. Some firewalls refuse datacenter addresses outright; those sites
are reported
unreachablerather than approached another way. - Nothing is cached between runs; every run reads the sites live.
Compliance
Business contact points only: role mailboxes published on the company's own site. Mailboxes that name a person and personal LinkedIn profiles are dropped. You are responsible for using the data lawfully, for example GDPR, CAN-SPAM and PECR for outreach.
Questions, bug reports and feature requests go on this actor's Issues tab. Business owners can send data-removal requests to info@locomint.io; that address is for removal requests only. This actor keeps no copy of what it reads between runs, so each run returns what the public pages show at that moment.
Other Locomint actors
- Google Maps Scraper & Email Extractor – Business Leads: Search terms and a city in, business records with website contacts out.
- Google Maps Scraper – Multi-City Lead Lists with Emails: Many categories across many cities in one deduplicated run.
- Google Maps Place Details Scraper – Bulk Place ID Lookup: Place IDs or place-page links in, full records out.
- Website Email Scraper – Contact Details, Socials & WhatsApp: Contact points from website URLs you supply.
- Website Content Crawler – Markdown for AI, Emails & Contacts: A whole site as Markdown, with its contact points.
- Bulk Email Verifier & Validator: Checks whether addresses can receive mail.
- AI Crawler Checker – robots.txt Rules for GPTBot & ClaudeBot: Which AI crawlers a site's robots.txt allows.
- Schema Markup Validator & Generator – JSON-LD Checker: Checks and generates schema.org markup.