# Company Domain Finder (`spookyweb/company-domain-finder`) Actor

Turn a list of company names into official websites and social profiles, with a confidence score, the signals that fired, and the rejected candidates and why. Directory and profile hosts are never returned as a company website.

- **URL**: https://apify.com/spookyweb/company-domain-finder.md
- **Developed by:** [丂卩ㄖㄖҜㄚ](https://apify.com/spookyweb) (community)
- **Categories:** Lead generation, Integrations, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.60 / 1,000 company resolveds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Company Domain Finder

Give it a list of company names and it returns the official website for each one, the social profiles that website publishes, a confidence score, and the candidate domains it rejected along with the reason.

### 🔍 What does Company Domain Finder do?

Company name in, **official domain out**. For every name you supply, Company Domain Finder gathers candidate domains from three independent sources, fetches each candidate homepage, and scores it against the name you asked for. The winner comes back with a `confidence` between 0 and 1 and a `matchedOn` list saying exactly which signals fired.

The easiest way to try it is to click **Try for free** and run it on the two names already in the input box. Paste your own list in and it will work the same way.

Matching a company name to a domain is a **judgement, not a lookup**, so this Actor never returns a guess dressed up as a certainty. A weak match comes back marked `ambiguous` with the runners up attached. A name with no findable website comes back `not_found` rather than as a plausible looking wrong answer.

Four statuses, and the difference between the last two is the one that saves you money:

| Status | What it means |
|---|---|
| `found` | One domain won clearly, and its own homepage was fetched and read |
| `ambiguous` | A domain is proposed but not confirmed: a close runner up, a score under your bar, or a homepage that did not respond |
| `not_found` | The lookup ran in full and no candidate survived. Either this company has no findable website, or every candidate found refused to answer, which `sourcesUnavailable` and `error` tell apart |
| `unavailable` | Wikidata or the search index could not be reached, so the candidates were never gathered and the company was never looked up. Worth running again, and **not charged** |

### 📊 What data can I extract?

One row per company, whatever the outcome:

| Field | Type | What it is |
|---|---|---|
| `query` | string | The entry exactly as you supplied it, so rows line back up with your list |
| `companyName` | string | The name that was looked up |
| `domain` | string | The registrable domain judged to be the company's own website |
| `websiteUrl` | string | The homepage that was fetched and scored, after redirects |
| `confidence` | number | 0 to 1, how strongly the evidence supports the match |
| `matchedOn` | array | The signals that fired, such as `registry-match` or `name-is-domain` |
| `homepageVerified` | boolean | Whether the returned domain's own homepage was fetched and read, rather than the domain resting on a registry claim alone |
| `resolvedTitle` | string | The title tag of the page that was matched |
| `description` | string | The meta or Open Graph description the homepage publishes |
| `logoUrl` | string | The Open Graph image or touch icon, as an absolute URL |
| `country` | string | ISO 3166 alpha-2, from your request or inferred from the domain ending |
| `registeredAt` | string | When the domain was first registered, from RDAP |
| `domainAgeDays` | number | Whole days since registration. A three week old domain is not the company you asked for |
| `nameServers` | array | Nameservers the domain resolves through, lowercased and sorted |
| `registrar` | string | The registrar holding the domain. Not the owner, which every registry redacts |
| `socials` | object | `linkedin`, `x`, `facebook`, `instagram`, `youtube`, `tiktok`, `github` |
| `alternates` | array | Rejected candidates, each with its score and the reason it lost |
| `status` | string | `found`, `ambiguous`, `not_found` or `unavailable` |
| `sourcesUnavailable` | array | Which of `registry`, `search` and `homepages` failed to answer for this company. Empty when everything answered |
| `checkedAt` | string | When the lookup ran, ISO 8601 |
| `error` | string | Why a row without a confirmed answer is worth running again. Null on a confirmed row |

### 💡 Why find company domains?

**Name only lists.** A column of company names from a form, a badge scan or an old spreadsheet becomes a column of domains, with the ones that could not be resolved marked rather than dropped.

**The first field everything else asks for.** Contact address tools, technology lookups, headcount data and news feeds all take a domain as their input. This produces that field from a name.

**Deduplication.** "Apex Engineering Ltd" and "Apex Engineering" are two rows until both resolve to `apexengineering.co.uk`, at which point they are one account.

**Filings, directories and shortlists.** Paste the company names out of a document and get the website and social profiles for the whole set in one run.

**Agent tooling.** The output schema, the confidence score and `homepageVerified` are there so an AI agent can decide whether to trust a row or ask a human, rather than acting on a guess.

### 🚀 How do I use Company Domain Finder?

1. Click **Try for free**.
2. Put your company names into `companies`. Plain strings are fine, and objects with `name`, `country`, `city` and `hint` disambiguate the common names.
3. Set `country` to an ISO 3166 alpha-2 code such as `GB` if your whole list is from one market.
4. Leave `minConfidence` at `0.4` unless you want a stricter bar for a row to count as confirmed.
5. Click **Start**, then download the results as JSON, CSV or Excel, or read them from the API.

### ⬇️ Input

```json
{
  "companies": [
    "Monzo Bank",
    { "name": "Apex Engineering", "country": "GB", "city": "Manchester" }
  ],
  "country": "GB",
  "minConfidence": 0.4,
  "includeSocials": true,
  "maxCandidates": 5
}
```

| Field | Type | Default | What it does |
|---|---|---|---|
| `companies` | array | required, prefilled with `["Monzo Bank", "Patagonia"]` | Names as strings, or objects with `name` plus optional `country`, `city` and `hint`. A run with no names fails rather than finishing empty, so a broken integration is visible instead of silent |
| `country` | string | none | ISO 3166 alpha-2 code applied to every entry without its own country |
| `minConfidence` | number | `0.4` | Below this a row is flagged `ambiguous` rather than `found`. Nothing is ever hidden |
| `includeSocials` | boolean | `true` | Read social profile links from the matched homepage markup |
| `maxCandidates` | integer | `5` | Candidate homepages fetched and scored per company, 1 to 10 |

### ⬆️ Output

#### Table view

Results arrive as a Companies table you can sort and filter in the Console, with the company, the domain, the confidence, the status, whether the homepage was read, any source that did not answer, the signals that matched, the page title, the country, the socials and the rejected candidates lined up per row.

#### JSON

Two real rows, copied out of a run of the code that is in this Actor today, on 15 August 2026. Nothing here is tidied up: `country` is null because the request did not state one and `.com` implies nothing, two of the seven social slots are empty because the Monzo homepage does not link them, and the rejected candidates are whatever the run actually threw away.

```json
{
  "query": "Monzo Bank",
  "companyName": "Monzo Bank",
  "domain": "monzo.com",
  "websiteUrl": "https://monzo.com/",
  "confidence": 0.99,
  "matchedOn": [
    "registry-match",
    "name-in-domain",
    "name-on-homepage",
    "social-handle-match",
    "top-search-result",
    "established-domain"
  ],
  "homepageVerified": true,
  "resolvedTitle": "Monzo | Open a Free Account",
  "description": "Your salary sorted into Pots. Your spare change turned into savings. Your money, doing what it should with Monzo.",
  "logoUrl": "https://images.ctfassets.net/ro61k101ee59/2TTYm6n3SCsWCaZnIT3Vo1/dd3379fae4c09ed2c86a4e7effafaace/Open_Graph_monzo.com__50_.jpg",
  "country": null,
  "registeredAt": "1998-01-19T05:00:00Z",
  "domainAgeDays": 10435,
  "nameServers": ["curt.ns.cloudflare.com", "kara.ns.cloudflare.com"],
  "registrar": "Amazon Registrar, Inc.",
  "socials": {
    "linkedin": "https://www.linkedin.com/company/monzo-bank",
    "x": "https://twitter.com/monzo",
    "facebook": "https://www.facebook.com/monzobank",
    "instagram": "https://www.instagram.com/monzo",
    "youtube": "https://www.youtube.com/monzobank",
    "tiktok": null,
    "github": null
  },
  "alternates": [
    { "domain": "moneysupermarket.com", "confidence": 0, "reason": "homepage could not be fetched: HTTP 403" },
    { "domain": "bankchart.co.uk", "confidence": 0.13, "reason": "nothing tied this domain to the company name" },
    { "domain": "monzobank.com", "confidence": 0, "reason": "homepage could not be fetched: fetch failed" },
    { "domain": "monzobank.io", "confidence": 0, "reason": "homepage could not be fetched: fetch failed" },
    { "domain": "wikipedia.org", "confidence": 0, "reason": "directory, registry or social profile host, never a company website" },
    { "domain": "google.com", "confidence": 0, "reason": "directory, registry or social profile host, never a company website" },
    { "domain": "monzobank.co", "confidence": 0, "reason": "beyond maxCandidates, 5 domains were checked" },
    { "domain": "monzobank.net", "confidence": 0, "reason": "beyond maxCandidates, 5 domains were checked" }
  ],
  "status": "found",
  "sourcesUnavailable": [],
  "checkedAt": "2026-08-15T16:51:55.553Z",
  "error": null
}
```

And the second row from the same run, for a company name that was invented so there would be nothing to find. Every promised field is present, the ones with no answer are null, and the candidates that were tried are listed with the reason each one lost:

```json
{
  "query": "Zzqxwv Fabrication Holdings",
  "companyName": "Zzqxwv Fabrication Holdings",
  "domain": null,
  "websiteUrl": null,
  "confidence": 0,
  "matchedOn": [],
  "homepageVerified": false,
  "resolvedTitle": null,
  "description": null,
  "logoUrl": null,
  "country": null,
  "registeredAt": null,
  "domainAgeDays": null,
  "nameServers": null,
  "registrar": null,
  "socials": {
    "linkedin": null, "x": null, "facebook": null, "instagram": null,
    "youtube": null, "tiktok": null, "github": null
  },
  "alternates": [
    { "domain": "afab.co.uk", "confidence": 0.18, "reason": "nothing tied this domain to the company name" },
    { "domain": "wix.com", "confidence": 0.13, "reason": "nothing tied this domain to the company name" },
    { "domain": "dhd-eng.com", "confidence": 0.13, "reason": "nothing tied this domain to the company name" },
    { "domain": "fca.org.uk", "confidence": 0.13, "reason": "nothing tied this domain to the company name" },
    { "domain": "zzqxwvfabrication.com", "confidence": 0, "reason": "homepage could not be fetched: fetch failed" },
    { "domain": "gov.uk", "confidence": 0, "reason": "directory, registry or social profile host, never a company website" },
    { "domain": "google.com", "confidence": 0, "reason": "directory, registry or social profile host, never a company website" },
    { "domain": "service.gov.uk", "confidence": 0, "reason": "directory, registry or social profile host, never a company website" },
    { "domain": "zzqxwvfabrication.io", "confidence": 0, "reason": "beyond maxCandidates, 5 domains were checked" },
    { "domain": "zzqxwvfabrication.co", "confidence": 0, "reason": "beyond maxCandidates, 5 domains were checked" }
  ],
  "status": "not_found",
  "sourcesUnavailable": [],
  "checkedAt": "2026-08-15T16:51:56.766Z",
  "error": null
}
```

### Where the candidates come from

Three independent sources, because no one of them is reliable on its own.

1. **[Wikidata](https://www.wikidata.org).** It states official websites as a claim on the company itself, which is the strongest evidence available without paying anyone. Two calls to `wikidata.org/w/api.php`, a name search and then the claims. Only entities whose label agrees with your name are used, so the village of Monzon does not answer for Monzo.
2. **[DuckDuckGo](https://html.duckduckgo.com/html/).** Your name, plus any country, city or hint you gave, sent once per company to `html.duckduckgo.com`, unauthenticated. Aggregators are stripped out of the results before anything is fetched.
3. **The name itself.** `apexengineering.com`, `apexengineering.co.uk` and so on. Cheap, and right more often than it has any business being.

Then [RDAP](https://rdap.org) for the registration date and nameservers, which is free, keyless and standardised, and the candidate homepages themselves.

Everything is plain HTTP. No browser, no paid API, no key of yours or ours.

**Worth knowing before you buy.** The DuckDuckGo endpoint is the least stable part of this Actor. It is a public HTML page rather than an API, nobody promises it to us, and if it starts refusing requests the search source goes with it. That is why the Actor does not lean on it alone: Wikidata and the name itself resolve plenty of companies without it, a lookup that loses a source says so in `sourcesUnavailable` rather than pretending, and a lookup that never got its candidates gathered is not charged for.

### How the confidence score is worked out

Each candidate homepage is fetched and checked for the signals below. They add up, and the total is capped at 1.

| Signal | What it means |
|---|---|
| `registry-match` | An open registry states this domain is the company's official website |
| `established-domain` | Registered more than two years ago, so it is not a fresh lookalike |
| `name-is-domain` | The domain label is exactly the company name with the spaces closed up |
| `name-in-domain` | The company name is contained in the domain label |
| `exact-name-in-title` | The full company name appears in the page title |
| `name-in-title` | Every word of the name appears in the page title |
| `name-on-homepage` | The full company name appears in the homepage text |
| `social-handle-match` | A social profile the homepage links to carries the company's handle |
| `top-search-result` | The domain was the first non directory result |
| `in-search-results` | The domain appeared further down the results |
| `country-match` | The domain ending matches the country you asked for |

Two rules stop a plausible wrong answer getting through. **A candidate with no name signal is never returned**, however well it ranked in a search, so a nonsense name comes back `not_found` instead of resolving to whatever happened to be first. And **a domain ending that contradicts your requested country is penalised**, so asking for a UK company and being handed the Italian arm of a group at full confidence cannot happen.

Where the best and second candidate finish within 0.1 of each other, the row is `ambiguous` even if the score is high. Two candidates that close means the Actor cannot tell them apart, and saying so is worth more than a coin toss.

**A score is not a confirmation.** A registry claim scores well on its own, and some sites answer a plain homepage request with a 403 or a 404 while being perfectly real. When the winning domain's own homepage never responded, the row carries `homepageVerified: false` and comes back `ambiguous` rather than `found`, however high the score, with the reason in `error`. The domain is still there and still probably right. It just has nothing behind it that this Actor saw with its own eyes, and a row that cannot tell you that is asking you to trust it blindly.

### The aggregator trap

Search results for any company name fill up with pages **about** the company rather than pages **by** it: LinkedIn, Crunchbase, Bloomberg, Companies House mirrors, Yell, Glassdoor, Trustpilot. None of those is the company's own website, and returning one is the most damaging mistake this Actor could make, because it is only caught after somebody has acted on it.

Company Domain Finder keeps a denylist of those hosts and never returns one as `domain`. They appear in `alternates` with the reason, so you can see they were considered and thrown out rather than missed.

The denylist has one deliberate exception. Someone looking up "LinkedIn" wants `linkedin.com`, so a host stops counting as an aggregator when the name being searched is that aggregator's own brand. Country versions are covered too, which matters more than it sounds: `google.com` being on a list that `google.co.uk` was missing from is exactly how a made up company name once resolved to a search engine.

### Limits

- Social profiles are read from the matched homepage's own markup. That means a company whose footer does not link its accounts returns nulls, and it also means this Actor never contacts a social platform, so nothing here is affected by their blocking.
- A homepage that requires JavaScript to render its text may score lower on the page signals, because no browser is used. The domain and registry signals are unaffected.
- Only the first candidate homepage per domain is read. This finds the website, it does not crawl it.
- `maxCandidates` caps how many domains are checked. Anything beyond the cap is listed in `alternates` saying so, rather than quietly dropped.
- A run stops early if five companies in a row come back `unavailable`, because that means a source is down rather than the list being unusual. The rows already resolved are kept and the log says the run stopped.
- A run with no company names in it fails rather than finishing green with an empty dataset, so a broken integration is visible on the run list instead of looking like a list nobody could resolve.

### 💰 How much does it cost?

Charged **once per company name**. A name that resolves cleanly, one that comes back ambiguous and one with no findable website all cost the same, because proving a company has no website costs the same fetches as finding one.

Company resolved, per lookup:

| Free | Bronze | Silver | Gold | Platinum | Diamond |
|---|---|---|---|---|---|
| $0.0189 | $0.016065 | $0.01323 | $0.01134 | $0.00945 | $0.00756 |

A thousand company names on the Bronze plan is **$16.065**, and on Diamond **$7.56**. Apify's own Actor start event is charged on top at $0.00005 a run, once, because this Actor caps its memory at 1 GB.

**A company that was never looked up is not charged.** Candidates come from Wikidata and the search index. If one of those refuses the request and nothing survives, the row comes back `unavailable`, `sourcesUnavailable` names what went missing, and no `company-resolved` event fires for it. You pay for answers, including the answer "this company has no website", and not for a lookup that never happened.

That is about the source, not about the company. A name whose candidate homepages were all found and all refused to respond **is** charged, because the lookup ran in full: both sources answered, every candidate they produced was fetched, and "no reachable website" is the answer. Those rows come back `not_found` carrying `homepages` in `sourcesUnavailable` and an `error` saying they may improve on a retry, so you can tell them apart from a company that genuinely publishes nothing.

If five companies in a row come back `unavailable`, a source is down rather than the list being unusual, and the run stops there and says so in the log. You keep the rows already resolved, and the rest of the list is left for a later run rather than burned against a source that is not answering.

The price does not move with `maxCandidates`, how many sources answered, or how many social profiles were found.

You can cap what a run is allowed to spend before you start it. The lowest cap this Actor accepts is **$0.02**, which is the start event plus one lookup, because a cap below that could not pay for a single result and would stop the run without returning anything.

### 🔌 Integrations

Send results straight to Google Sheets, Slack, Airtable, Zapier, Make or your own webhook using [Apify integrations](https://docs.apify.com/platform/integrations). Runs can be [scheduled](https://docs.apify.com/platform/schedules), monitored, and triggered by an event in another tool, so a weekly list of new accounts can be resolved without anyone opening the Console.

### 🔗 Using Company Domain Finder with the Apify API

```bash
curl -X POST "https://api.apify.com/v2/acts/spookyweb~company-domain-finder/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"companies": ["Monzo Bank", "Patagonia"], "country": "GB"}'
```

Or with the Apify client:

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('spookyweb/company-domain-finder').call({
  companies: ['Monzo Bank', { name: 'Apex Engineering', country: 'GB', city: 'Manchester' }],
  minConfidence: 0.4,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

Full detail is in the [Apify API reference](https://docs.apify.com/api/v2), and every run is also callable from the [Python](https://docs.apify.com/api/client/python) and [JavaScript](https://docs.apify.com/api/client/js) clients.

### ❓ FAQ

#### What does the confidence score actually mean?

It is the weighted sum of the signals listed above, capped at 1. A domain stated by an open registry, matching the name exactly, and carrying the company's name in its page title will sit near 1. A domain that only looks right will sit near 0.3. Read `matchedOn` alongside it, because the same score can be reached different ways and the list tells you which.

#### Why did I get a row marked ambiguous with a high confidence?

Because a second candidate scored within 0.1 of it. That usually means a group runs more than one legitimate domain, or two real businesses share a name. Both are in `alternates`, so you can pick.

#### Will it ever return a LinkedIn or Crunchbase page as the website?

No. Directory, registry and social profile hosts are on a denylist and are never returned as `domain`. They show up in `alternates` with the reason. The one exception is when you are actually searching for that company, so looking up "LinkedIn" does return `linkedin.com`.

#### What happens to a company with no website at all?

You get a row with `status` set to `not_found` and `domain` set to null. That is a real finding rather than a failure, and the run finishes successfully. The candidates that were tried are in `alternates` with the reason each one lost.

#### How do I tell "no website" apart from "the site was down"?

Read `status` alongside `sourcesUnavailable`. `unavailable` means Wikidata or the search index refused the request, so the candidates were never gathered and nothing was really checked. `not_found` with an empty `sourcesUnavailable` means the lookup ran in full and this company has no findable website, which is a real result you can act on. `not_found` carrying `homepages` is the middle case: candidates were found, every one of them was fetched, and none of them answered. `error` says which of the three happened in a sentence, and all three are worth a second run except the middle one, which usually means the sites are genuinely down or refusing automated requests.

#### Why is a row ambiguous when the confidence is high?

Either a second candidate finished within 0.1 of the winner, or `homepageVerified` is false. The second one is the interesting case: the domain was claimed by the registry and matches the name, but its homepage answered with an error or a timeout when the Actor tried to read it, so there is nothing confirming the claim. Some perfectly real sites do this to a plain HTTP request. Treat the domain as a strong lead and check it yourself, rather than as a verified answer.

#### Can I look up companies outside the UK and the US?

Yes. The country hint is optional and the Actor works on any market. Setting `country` adds that market's domain endings to the candidates tried and puts the country into the search, which improves the answer for common names.

#### How do I disambiguate two companies with the same name?

Pass an object instead of a string: `{ "name": "Apex", "country": "GB", "city": "Manchester", "hint": "structural steel" }`. The city and hint go into the search, which is usually the difference between the right company and a coin toss.

#### Does it use my API keys, or anyone else's?

No. Every source is public and keyless, which is why the price is what it is.

### ⚖️ Is it legal to find company domains?

Yes. This reads publicly available information: an open knowledge base, a public search index and the homepages companies publish themselves. It handles business information rather than personal data, it does not log in anywhere, and it does not use breach data or scraped private databases.

Social profile URLs are read from a company's own website markup, so no social platform is ever contacted and their terms of service do not come into it. What you do with the results afterwards is yours to get right: if you go on to contact named people, UK GDPR and its equivalents make you the data controller for that. Apify's [ethical scraping guide](https://blog.apify.com/is-web-scraping-legal/) covers the wider picture.

### 👍 Your feedback

Found a bug, or want a field that is not here yet? Open an issue on the Actor's Issues tab. Requests that make the data more useful get built, and problems get fixed quickly.

### 🔎 You might also like

| Actor | What it does |
|---|---|
| [Company Email Finder](https://apify.com/spookyweb/company-email-finder) | Contact addresses, the email naming convention behind them, and MX validation |
| [Website Contact Scraper](https://apify.com/spookyweb/website-contact-scraper) | Emails, phones, socials and addresses from company websites, one record per domain |

# Actor input Schema

## `companies` (type: `array`):

The companies to look up. Give plain names as strings, or objects with a name plus any of country, city and hint to tell two businesses of the same name apart. Every entry produces one row whatever the outcome.

## `country` (type: `string`):

An ISO 3166 alpha-2 code such as GB or US, applied to every entry that does not carry its own country. It steers the search and adds that market's domain endings to the candidates tried.

## `minConfidence` (type: `number`):

Between 0 and 1. A winning domain scoring below this is still returned, flagged as ambiguous rather than found, so nothing is ever hidden from you. Default 0.4.

## `includeSocials` (type: `boolean`):

Read LinkedIn, X, Facebook, Instagram, YouTube, TikTok and GitHub links from the company's own homepage markup. No social platform is ever contacted.

## `maxCandidates` (type: `integer`):

How many candidate homepages are fetched and scored for each company. More candidates find awkward names more often and take longer. Default 5.

## Actor input object example

```json
{
  "companies": [
    "Monzo Bank",
    "Patagonia"
  ],
  "country": "",
  "minConfidence": 0.4,
  "includeSocials": true,
  "maxCandidates": 5
}
```

# Actor output Schema

## `results` (type: `string`):

One row per company looked up, carrying the domain, the confidence, the signals that matched, the social profiles and the rejected candidates.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "companies": [
        "Monzo Bank",
        "Patagonia"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("spookyweb/company-domain-finder").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "companies": [
        "Monzo Bank",
        "Patagonia",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("spookyweb/company-domain-finder").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "companies": [
    "Monzo Bank",
    "Patagonia"
  ]
}' |
apify call spookyweb/company-domain-finder --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,spookyweb/company-domain-finder"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/7jgMA1I35T4EqNhWW/builds/uF432Hp4JxNFKRvs6/openapi.json
