# Company Contact Finder: Name to Website, Emails and Phones (`rich_minds/company-contact-finder-ai`) Actor

First 25 company contacts free. Company contact finder: type company names, get the official website and the checked email to write to — pay per qualified company contact, junk never charged by us. Find company email by name, verify company email, phones. MCP-ready. Free demo on any plan.

- **URL**: https://apify.com/rich_minds/company-contact-finder-ai.md
- **Developed by:** [Rich Minds](https://apify.com/rich_minds) (community)
- **Categories:** Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $7.50 / 1,000 qualified company contact (rules only)s

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Company Contact Finder: Name to Website, Emails and Phones

**Company names in, the checked email to write to out — every week.**

⚡ First **25 company contacts free** · 💵 **$0.0075** per company contact · 🤖 **≈ $0.024** with the AI check, tokens included · ⏱️ 4–5 of 5 with a contact, 6.7–36 s on Apify

![Sample output — the Shortlist view: the purchasing, sales and general inbox to write to, checked, with the first line of the e-mail](https://api.apify.com/v2/key-value-stores/EuK0j9qthGMva06Kg/records/shortlist.svg)

> **Try it in 30 seconds.** Click **Try it** — the form is pre-filled with a free demo of 4 labelled sample
> companies. Type your own, one per line (`Name, country`), and press Start — on **any Apify plan**; your first **25** are free.
> → [What a run costs](#-pricing--what-a-run-really-costs) · [What the AI adds](#-what-the-ai-tier-adds) · [Run it weekly](#-run-it-weekly)

### ⚡ At a glance

| | |
|---|---|
| **What you get** | Per company: the website, every e-mail checked, phones, VAT ID, address — and the address to write to |
| **You provide** | Names with their country (`Hamburg Textil Import GmbH, DE`), a file — or no list: a keyword (`textile importers, DE`) or a directory page |
| **Typical run** | websites given: 5 of 5 in 6.7 s · names only: 4 of 5 in 36 s (Apify, 2026-10-23) |
| **Cost of that run** | $0.03–0.04 rules only · ≈ $0.10–0.12 with the AI check — inside your free 25 |
| **Free tier** | Your first 25 company contacts on this Actor — one free tier per Apify account |
| **Add-ons** | Website only $0.002 · named people's e-mails $0.01 each · SMTP mailbox check $0.002 — all off by default |
| **Keys / setup** | No key for the search. AI: none on paid Apify plans (model access included); on the Free plan your own Gemini / Groq key — free: 1–3 AI verdicts per run, paid: every company |
| **Which plan** | Any plan — the free demo, the live search and your own list ([template](https://api.apify.com/v2/key-value-stores/EuK0j9qthGMva06Kg/records/list-template.json)) |
| **Agencies** | 10 clients × 200 companies a month (80 % hit rate) ≈ $12 rules · ≈ $38 with AI |
| **Works with** | HubSpot (native), schedules, webhooks, Sheets, Make / n8n, Slack, Teams, MCP & AI agents |

### 🎯 What this Actor does

- **Name → website** — the official site from the name and country; directories and social sites skipped.
- **No list? Companies by keyword or directory** — `textile importers, DE`, or an exhibitor list URL, becomes the list.
- **Contacts on the company's own pages** — e-mails (also `name [at] firm [dot] de`), phones, contact form, LinkedIn.
- **Every e-mail checked** — syntax, MX over DNS, disposable, role account, typos.
- **The one to write to** — purchasing, export, sales or general, in your order; plus VAT ID and address.

#### 🔎 Company website finder — or the domain alone

One Google page per company; a namesake abroad loses (domain, country TLD, legal name, VAT number decide). **Website only**: the website and its evidence, $0.002.

#### 🧭 No list yet? Find companies by keyword or from a directory page

**Find companies by keyword** turns `textile importers, DE` into the company sites Google lists (directories and "top 10" articles skipped). **Companies from a directory page** reads an exhibitor or member list. `foundBy` names the search or page.

#### ✉️ Verify company email addresses before you send

`ok` (the domain takes mail), `risky` (no MX) or `invalid`. **Check the mailbox itself** adds an SMTP check (`mailboxStatus`), $0.002 + $0.00089 on your account.

#### 🏢 Company enrichment: VAT ID, address, industry

VAT ID, postal address and headcount as the imprint prints them (`vatId`, `address`, `employeesHint`); the AI adds `industry` — in the **CRM import** view.

#### 👤 Named people's e-mails

With the AI on: an address per person on the team page from a colleague's printed one (`m.brandt@` → `j.petersen@`), $0.01 each.

#### 📄 From a CSV, Excel or Google Sheet — into HubSpot

**Companies from a file** maps the columns by header; a **HubSpot private-app token** pushes every new company.

### 🚀 How to use it

1. **Click Try it** — the demo of 4 labelled sample companies runs, free.
2. **Type your companies** (`Name, CC` or `Name, CC, website.com`) — or a keyword. Keep **AI contact check** on.
3. **Press Start** — the best address of each company first; export it or push it to HubSpot.
4. **Schedule it weekly** with **E-mail me the new company contacts** — only new companies are charged.

![Sample output — the Outreach view: contact route, the inbox, why it was picked, the named people and the first line](https://api.apify.com/v2/key-value-stores/EuK0j9qthGMva06Kg/records/outreach.svg)

#### 📦 Already using vdrmota/contact-info-scraper? Check your scraped data

Send its dataset (`sourceMode: dataset`): merged per domain, every address checked.

📚 **Learn more:** [Tutorial — find the email to write to from a list of company names](https://api.apify.com/v2/key-value-stores/EuK0j9qthGMva06Kg/records/tutorial.html)

### 🆚 Why this instead of running Contact Details Scraper?

| | By hand: Google search + the company's contact page | Google Search Scraper + Contact Details Scraper (`vdrmota/contact-info-scraper`, 3,638 users / 30 d) | **This Actor** |
|---|---|---|---|
| **Your time per 100 company contacts** | ≈ 7 h (≈ 4 min each, on 5 sample companies) | ≈ 3 h: pick each site and address | ≈ 20 min: the doubtful rows |
| **Starts from** | a name | a website list | **a name**, a keyword or a directory page |
| **E-mails** | by eye | every address, unchecked | MX-checked, the inbox picked |
| **Same 100 company contacts, all in** | $0 + ≈ 7 h | ≈ $1.65 (100 Google + 600 site pages) + your picking | **$0.75** rules only · **≈ $2.40** with the AI check — 100 checked, inbox picked, junk $0 |

#### vs other company contact finders

| Actor | 100 companies | Pays for | What it lacks |
|---|---|---|---|
| **This Actor** | **$0.75** rules only · ≈ $2.40 AI | each company with a checked contact | LinkedIn profiles (dated 2026-11-06) |
| [nexgendata/company-email-finder](https://apify.com/nexgendata/company-email-finder) | $10.00 + start fee | every row | needs domains; 20 % of runs fail (30 d) |
| [runtime/company-role-contact-finder](https://apify.com/runtime/company-role-contact-finder) | $3.00 + start fee | every role-contact row | 4× our price per row; 3 of 40 runs timed out (measured, 30 d) |
| [tagadanar/french-company-contacts](https://apify.com/tagadanar/french-company-contacts) | $0.60 + start fee | each company + each e-mail | France only (its input) |
| [Hunter.io free plan](https://hunter.io/pricing) | free, 25 searches a month | person patterns and its own verifier | needs the domain first |

Also: [apify/google-search-scraper](https://apify.com/apify/google-search-scraper) (no contacts) · [clearpath/email-finder-api](https://apify.com/clearpath/email-finder-api) (needs the domain) · [bounceverify](https://apify.com/bounceverify/bounceverify-email-verifier) (SMTP only, built in) · more.

### 💵 Pricing — what a run really costs

| Event | When it is charged | Price |
|---|---|---|
| `free-tier` | your first 25 company contacts on this Actor | **$0.00** |
| `qualified-company-contact-basic` | a company with a website and a checked e-mail, by the rules | **$0.0075** |
| `qualified-company-contact-ai` | the same + the AI check: named people, industry, your first line | **$0.02** |
| `website-found` | **Website only** on: one company's website, confidence and evidence | **$0.002** |
| `named-person-email` | add-on: one pattern-derived named person's address | **$0.01** |
| `mailbox-verified` | add-on: the SMTP check of one company's best address (+ $0.00089 on your account) | **$0.002** |

**One free tier:** your first 25 company contacts are free, whatever the tier, add-ons included. **Never charged:** companies with no website or no usable address, duplicates, already received companies, rows below **Minimum score**, the keyword search and the directory page. No source bill — a Store fallback runs on your account only when Google or a site refuses, capped at $0.50.

**How that compares** — same-job contact finders charge a median $0.0075; $0.0075 here is 1.0× that, but only per company with a checked contact — one replaces ≈ 6 raw rows: $0.0017 per raw-row equivalent.

**Worked example** (live run on Apify, 2026-10-23) — 5 real steel makers by name: 4 with a checked contact, 1 free → 4 × $0.0075 = **$0.03**; with the AI 4 × ($0.02 + ≈ $0.004 tokens) = ≈ $0.10. Both inside the free 25.

**AI tier, all in:** ≈ $0.024 per company — $0.02 + ≈ $0.004 tokens (2,045 in / 377 out — gemini-3.5-flash-lite, own key, 2026-10-23 — at the default Apify model's rate). The Apify-model path gets its platform measurement on 2026-10-30.

**At volume** — 500 importer names a month (80 % hit rate): $3.00 · ≈ $9.60 with AI. An agency's 2,000-row CRM export as a file (80 % hit rate): $12 · ≈ $38.

### 🤖 What the AI tier adds

Nordhafen Textilhandel GmbH, a fictional sample record (sample output), AI **off**:

```json
{"name": "Nordhafen Textilhandel GmbH", "bestEmail": "einkauf@nordhafen-textilhandel.de", "bestEmailRole": "purchasing", "people": [], "generatedText": "Write to einkauf@nordhafen-textilhandel.de — the purchasing inbox of Nordhafen Textilhandel GmbH (MX ok, listed on /kontakt).", "assessedBy": "rules"}
```

AI **on** (sample output — a local run with an own Gemini key, 2026-10-23) — it found the head of purchasing and wrote the first line in German:

```json
{"name": "Nordhafen Textilhandel GmbH", "bestEmail": "einkauf@nordhafen-textilhandel.de", "people": [{"name": "Markus Brandt", "title": "Leitung Einkauf", "email": "m.brandt@nordhafen-textilhandel.de"}, {"name": "Jana Petersen", "title": "Vertrieb Export", "email": null}], "generatedText": "Guten Tag Markus Brandt, ich habe gesehen, dass Sie Baumwoll- und Leinenstoffe importieren. Wir bieten hochwertige Bio-Baumwoll-Jerseys für EU-Textilimporteure an und würden uns über eine Zusammenarbeit freuen.", "fitScore": 97, "aiModel": "google:gemini-3.5-flash-lite", "assessedBy": "ai"}
```

By hand — the right namesake, the team page, the first line — ≈ 4 minutes per company (on 5 sample companies).

**Which AI your plan gets:** paid plans via Apify's model access; the Free plan with your own key ([free Gemini key](https://aistudio.google.com/apikey): 1–3 verdicts per run); else sample verdicts.

### ⚙️ Input

| Field | Default | What it does |
|---|---|---|
| `companies` | — | one per line, `Name, CC` or `Name, CC, website` |
| `searchQuery` | — | no list: one keyword search per line, `textile importers, DE` |
| `maxSearchResults` | `20` | companies per keyword search |
| `listPageUrl` | — | an exhibitor / member directory page |
| `companiesFileUrl` | — | a CSV / XLSX link or a shared Google Sheet |
| `sourceMode` | `"live"` | the mode that runs = `sourceMode`, except `{}` = the free demo; `dataset` / `list`: your rows |
| `domainOnly` | `false` | the website alone, $0.002, no contacts |
| `enableAi` | `true` | the AI contact check |
| `minScore` | `30` | contact quality floor; below it not charged |
| `maxQualified` | `100` | cap on rows and spend |
| `notifyEmail` | — | the digest by e-mail after every run |
| `dedupeTtlDays` | `0` | re-check a company after N days (90 = quarterly) |

<details><summary>Every other input</summary>

`preset`, `goalDescription`, `preferRoles`, `includeNotFound`, `derivePersonEmails`, `verifyMailbox`, `hubspotToken`, `maxDiscoveryChargeUsd`, `datasetId`, `itemsList`, `targetFlags`, `suppressionList`, `llmProvider`, `llmApiKey`, `sendAlertsTo`, `webhookUrl`, `dedupeAcrossRuns`, `historyDatasetName`; API-only: `pagesPerSite`, `includePhones`, `llmModel`, `autoSwitchToLive`, `failOnSourceError`, `useStoreFallback` … — defaults, flags and tested combinations in the API reference.

</details>

### 📤 Output

**Upsert key:** `dedupeKey` — `domain:<normalised domain>`, stable across runs. **Sort** by `score`; `ruleScore` is the rule part, `fitScore` the AI's — trend across runs on `ruleScore`. **Views:** Shortlist, Outreach, CRM import, Website check, Score breakdown, Export. `OUTPUT` = the full run record; `RUN_SUMMARY` = the same record, same keys — next to a Markdown `DIGEST` and an HTML `REPORT`.

<details><summary>Every field of the row (each explained, with a sample row, in the API reference)</summary>

Field meanings: `itemId`, `dedupeKey`, `name`, `url`, `inputName`, `inputCountry`, `website`, `domain`, `websiteConfidence`, `websiteEvidence`, `websiteOnly`, `legalName`, `vatId`, `address`, `employeesHint`, `industry`, `foundBy`, `emails`, `bestEmail`, `bestEmailRole`, `bestEmailStatus`, `bestEmailReason`, `mailboxStatus`, `mailboxReason`, `contactRoute`, `phones`, `contactPageUrl`, `contactFormUrl`, `socials`, `people`, `sourcePath`, `notFound`, `notFoundReason`, `flags`, `targetFlagsMatched`, `ruleScore`, `score`, `label`, `fitScore`, `assessedBy`, `scoreReasons`, `summary`, `generatedText`, `recommendedNextStep`, `aiModel`, `chargedEvent`, `billedAs`, `source`, `checkedAt`.

</details>

### 🔁 Run it weekly

1. Put your address in **E-mail me the new company contacts** — the digest arrives after every run.
2. After your first real run, open the saved task its status links and click **Schedule** (weekly).
3. Feed it new names — a keyword search, a buyer finder's dataset or the Google Sheet of **Companies from a file**; companies you already have are skipped, free.
4. Add your **HubSpot private-app token**, or start a sheet from the [tracker template](https://api.apify.com/v2/key-value-stores/EuK0j9qthGMva06Kg/records/tracker.csv) — upsert on `dedupeKey`; **Keep a running log** (`historyDatasetName`) keeps every week in one dataset.

The same list in week 2 delivers 0 rows and costs $0 — a list renews by your new names.

#### 🔄 Keep your CRM's addresses fresh

**Re-check my company contacts every … days** = 90 on a schedule: 2,000 re-checked quarterly (80 % hit rate) ≈ $12.

#### 🎯 Try it for your niche

Pick one in **Start from a ready list** and press Start.

<details><summary>5 ready lists — names, a keyword search, a directory page</summary>

| Preset | What it finds |
|---|---|
| `steel-buyers` | purchasing inboxes of 5 steel makers — measured on Apify: 4 of 5 found (2026-10-23) |
| `coffee-importers` | the buying desks of 5 green-coffee importers — first run capped at $0.15 |
| `agency-crm-cleanup` | websites given (a CRM export) — capped at $0.15 |
| `textile-importers-search` | no list: 10 German textile importers by keyword — capped at $0.15 |
| `machine-builders-directory` | members linked from the VDMA directory page — capped at $0.15 |

</details>

### 🔌 Integrations, automation and API

- **HubSpot (native)** — a private-app token: each company upserted by domain, `bestEmail` as its contact; `OUTPUT.crm` counts them.
- **Webhook** — `webhookUrl` POSTs each company (or a batch) as JSON; contract below.
- **n8n / Google Sheets / Pipedrive** — [import the n8n template](https://api.apify.com/v2/key-value-stores/EuK0j9qthGMva06Kg/records/n8n-sheet-to-hubspot.json): a new Sheet row → this Actor → HubSpot; Apify's Google Sheets integration appends every run; Pipedrive via Make or n8n, upsert on `dedupeKey`.
- **After Contact Details Scraper or a buyer finder** — in `vdrmota/contact-info-scraper`'s Integrations tab, "Run succeeded" starts this Actor in `dataset` mode with `datasetId` = that run's dataset and `enableAi: false`.

<details><summary>Webhook contract and which delivery field wins</summary>

- **Webhook** — `webhookUrl` POSTs `{"event": "company_contact.qualified", "company_contact": {…}, "runId"}` per company, or with `webhookBatchSize` > 1 one `company_contacts.qualified` POST per batch (`company_contacts: […]`, `runId`). A 429 / 5xx is retried once; a failed POST never fails the run and is re-sent next run. `webhookSecret` signs it (`X-Signature`, HMAC-SHA256).
- **Which delivery field wins:** each URL is posted once; `webhookUrl` gets the rows as JSON, the per-service fields (API-only) the digest.

</details>

#### Run outcomes

<details><summary>What your integration sees, per outcome (every row in the API reference)</summary>

| Outcome | Run status | Dataset | `OUTPUT` | Charged? |
|---|---|---|---|---|
| Free demo (`{}`) | SUCCEEDED | 3 sample rows | `mode: demo`, `ok: true` | no |
| Success | SUCCEEDED | one row per company found | `outcome: ok`, `contacts` | per company contact |
| Nothing found | SUCCEEDED | empty (or free `notFound` rows) | `outcome: empty` | no |
| Your plan cannot run the Store fallback | SUCCEEDED; check `OUTPUT.ok` | Console: the free sample (`sampleFallback: true`); schedule / API: an alert to `notifyEmail` (`refusalAlerted`) | `ok: false`, `outcome: source_refused`, `sourceRefused: plan` | no |
| Source failed (file, directory page or dataset unreadable) | FAILED | empty | `outcome: source_failed`, `sourceError` | no |
| Source partial (a dataset run aborted) | SUCCEEDED | the rows read | `sourceStatus` (`partial: true`) | per company contact |
| AI unavailable | SUCCEEDED | rule rows | `aiError`, `aiCoverage` | basic price |

Branch on `OUTPUT.ok` / `OUTPUT.outcome` — never on an empty dataset. On a schedule send `failOnSourceError: true`.

</details>

<details><summary>List-mode rows — what a pasted record (or a file column) needs</summary>

| Field | Needed? | What it enables |
|---|---|---|
| `name` (or `companyName`, `company`, `consigneeName`, `buyerName`) | required | the company to find |
| `country` (or `countryCode`) | recommended | the country TLD and namesakes |
| `website` (or `domain`, `url`) | optional | skips the Google search |
| `city` | optional | kept in the row |
| `emails`, `phones` | optional | checked and picked from, no crawl |

</details>

<details><summary>API snippets — Python and JavaScript (the real search, a free first call commented)</summary>

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("rich_minds/company-contact-finder-ai").call(
    run_input={
        # free first call instead: {} or {"sourceMode": "list", "itemsList": [...]} — the labelled demo / your rows
        # copying the Console's JSON input? add "autoSwitchToLive": False
        "sourceMode": "live",
        "companies": ["Salzgitter AG, DE", "Tata Steel Limited, IN, tatasteel.com"],
        "enableAi": True,
        "maxQualified": 100,
        "maxDiscoveryChargeUsd": 0.5,
        "failOnSourceError": True,
    },
    timeout_secs=3240,  # 100 companies: 240 + 30 s × companies — see "How long does a run take?"
    # build="0.1.5",  # pin the build number your pipeline was tested with
)
out = client.key_value_store(run["defaultKeyValueStoreId"]).get_record("OUTPUT")["value"]
if not out.get("ok", True) or out.get("sourceError"):
    raise RuntimeError(out.get("sourceError") or out.get("error"))
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["name"], item["bestEmail"], item["score"], item["label"], item["url"])
```

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

const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });
const run = await client.actor('rich_minds/company-contact-finder-ai').call({
    // free first call instead: {} or { sourceMode: "list", itemsList: [...] } — the labelled demo / your rows
    // copying the Console's JSON input? add autoSwitchToLive: false
    sourceMode: 'live',
    companies: ['Salzgitter AG, DE', 'Tata Steel Limited, IN, tatasteel.com'],
    enableAi: true,
    maxQualified: 100,
    maxDiscoveryChargeUsd: 0.5,
}, { timeout: 3240 /* 100 companies: 240 + 30 s × companies; , build: '0.1.5' — pin the build number your pipeline was tested with */ });
const out = (await client.keyValueStore(run.defaultKeyValueStoreId).getRecord('OUTPUT')).value;
if (out.ok === false || out.sourceError) throw new Error(out.sourceError || out.error);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.map((i) => [i.name, i.bestEmail, i.score, i.label, i.url]));
```

</details>

**MCP & AI agents** — `{"mcpServers": {"apify": {"url": "https://mcp.apify.com/?actors=rich_minds/company-contact-finder-ai"}}}`, then ask *"Who should I email at Salzgitter AG?"*

**Minimal agent input** — memory off so a second ask answers again; your own rows: `{"sourceMode": "list", "itemsList": [{"name": "Salzgitter AG", "country": "DE"}]}`:

```json
{"sourceMode": "live", "companies": ["Salzgitter AG, DE"], "enableAi": true, "maxQualified": 10, "dedupeAcrossRuns": false}
```

**API reference:** [which call runs what, Tested combinations, the `OUTPUT` keys, a sample item](https://api.apify.com/v2/key-value-stores/EuK0j9qthGMva06Kg/records/api-reference.md).

### 👥 Who is it for?

| You are… | You run it to… | Start with |
|---|---|---|
| Exporter / sales team | importer names from customs data → the inbox for each | `steel-buyers` |
| Exporter without a list | importers in a country, by keyword | `textile-importers-search` |
| Trade-fair exhibitor | the exhibitor list → the buyer's inbox | `machine-builders-directory` |
| Agency / list builder | checked contacts with VAT ID for the CRM, into HubSpot | `agency-crm-cleanup` |
| Commodity exporter | the buying desks of importers and traders | `coffee-importers` |

### 🧠 How the AI works

- **Grounded** — one call picks the website among Google's candidates, a person only as printed, the address only among checked ones.
- **Model** — `google:gemini-3.5-flash-lite` with your own key (the token figures here). Via Apify: `anthropic/claude-haiku-4.5`, its platform run dated 2026-10-30.

### 🔒 Data, compliance and limits

- **Public B2B contacts only** — what a company publishes on its own site; no login, no LinkedIn.
- **GDPR / ePrivacy** — outreach needs a legitimate interest and an opt-out; a named person's address is personal data.
- **Polite crawl** — `robots.txt` honoured, ≤ 2 requests at a time per site.
- **SMTP only on opt-in** — port 25 is closed on Apify, so `ok` means the domain takes mail; **Check the mailbox itself** runs SMTP through bounceverify.

### ❓ FAQ

**How much will one run cost me?** $0.0075 per company with a checked contact, ≈ $0.024 with the AI; not-found companies and the first 25 are free.

**How do I find company email by name?** Type the name and the country; every address on its site is checked.

**Can I get the company name to domain match alone?** Yes — **Website only**: the website with its evidence, $0.002 each; no website, no charge.

**I have no list — can it find the companies?** Yes: a keyword and a country (`textile importers, DE`), or a directory page URL.

**How do I get importer contact details from customs data?** Paste the consignee names with their countries, link the export as a file, or run `dataset` mode on it.

**Is it a B2B email finder for people?** For the people a company names on its pages — printed, or built from a colleague's address ($0.01 each).

**How is this different from Hunter.io?** Hunter's free plan wins for a few person lookups a month on a domain you know; this starts from the name at $0.0075 per company found.

**What will my first real search cost?** 30 names at an 80 % hit rate: 24 free company contacts — $0.00.

**How long does a run take?** 4–5 of 5 with a contact, 6.7–36 s on Apify (2026-10-23); the AI measured ≈ 1.0–11.2 s per company (≈ 5–60 a minute) — gemini-3.5-flash-lite, own free Gemini key. One formula: `timeoutSecs` = 240 + 30 s × companies — 50 → 1740, 100 → 3240 — the worst case per 100 with a rate-limited own key; at the measured pace a run ends far sooner.

<details><summary>Measured per mode</summary>

| Mode | Measured | `timeoutSecs` |
|---|---|---|
| Free demo | 3–4 s on Apify | 120 |
| Live search, 5 real companies (Apify, 2026-10-23) | 4–5 of 5 with a contact, 6.7–36 s — websites given 6.7 s, names only 36 s; ≤ 7 s per company, 6 at a time | 240 + 30 s × companies |
| AI, free own key (`google:gemini-3.5-flash-lite`) | measured 2026-10-23: ≈ 1.0–11.2 s per company (≈ 5–60 a minute; 11.2 s on the latest run) with a free Gemini key; rate-limited, the AI stops after 2 min of waiting | the same |
| AI via Apify's model access (`anthropic/claude-haiku-4.5`) | not measured on the platform yet (dated 2026-10-30) | the same |

</details>

**Which Apify plan do I need?** Any plan for the demo, the search and your own list; the AI with Apify's model access (paid plans) or your own Gemini / Groq key on the Free plan.

**Do rule-scored company contacts use my free ones?** Yes — 5 of the 25 stay reserved for your first AI-checked ones while the AI is unavailable on your plan (the AI reserve).

**Will I be charged for the same company twice?** No — remembered by its domain, also when you add names or keywords; only **Re-check every … days** brings it back.

**How do I send the openers safely?** From your own mailbox, a few dozen a day; say who you are, add an opt-out, no tracking links in the first message.

**Is the data public / is this legal?** Only what each company publishes; the legal basis is yours.

**Can I use my own model?** Yes: `llmProvider: "byok"` plus `llmApiKey`.

⭐ **Found it useful? A review on the Store helps others find it.**

### 🧩 More Actors from the same developer

- **[Email List Cleaner](https://apify.com/rich_minds/email-list-qualifier-ai)** — check a whole address list before the campaign.
- **[Alibaba RFQ Leads AI](https://apify.com/rich_minds/alibaba-rfq-leads-ai)** — buyers asking for your product; find whom to write to here.
- **[OFAC Sanctions Screening](https://apify.com/rich_minds/counterparty-check-ai)** — screen these companies before the first offer.
- **[Local Business Leads](https://apify.com/rich_minds/local-business-lead)** — local firms from Google Maps, each with a checked e-mail.

### 🆘 Support

Something missing or wrong? Open an issue on the Actor's page — buyer requests ship first.

### 📝 Changelog

- **0.1.5** (2026-10-23) — Store listing and README wording updated so the Actor is easier to find and understand.
- **0.1.4** (2026-10-23) — No list needed: a keyword and a country, or a directory page, finds the companies.
- **0.1.3** (2026-10-23) — The live search starts again with the example input.
- **0.1.2** (2026-10-23) — "Website only" mode ($0.002 per website); companies from a CSV / Excel file or Google Sheet.
- **0.1.1** (2026-10-23) — first release: name → website → checked e-mail, the AI check.

### 🗓️ Coming next

- 2026-10-30 — the Apify-model AI measured on Apify · 2026-11-06 — LinkedIn profiles (opt-in).

# Actor input Schema

## `preset` (type: `string`):

Pick a ready list and press Start: it <b>replaces the free sample</b> with 5 real companies for that trade and runs the live search on any Apify plan (the untouched sample counts as empty); a value you typed yourself always wins. <b>Custom</b> = type your own companies below.

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

One per line: name, 2-letter country — <code>Hamburg Textil Import GmbH, DE</code>; add the website: <code>…, DE, hamburg-textil.de</code>. Typing here replaces the demo and starts the live search. Affects what you pay: only companies with a checked contact. Any Apify plan; a plan that cannot run Store Actors only skips the fallback.

## `searchQuery` (type: `string`):

One search per line: what the companies do, 2-letter country — <code>textile importers, DE</code>. The company sites Google lists become the companies (directories and 'top 10' articles skipped), each row naming its search in <code>foundBy</code>. Affects what you pay: only companies with a checked contact. Any plan; a plan that cannot run Store Actors only skips the fallback.

## `goalDescription` (type: `string`):

One sentence about your offer, e.g. <i>We sell organic cotton jersey to EU textile importers</i>. The AI uses it for the first line of your e-mail; the rules ignore it.

## `notifyEmail` (type: `string`):

After every run with at least one new company contact, the digest (found / not found, the inbox per company, the top 10 with their address) is e-mailed here through Apify's send-mail Actor. Schedule the run weekly and only new companies arrive. Never sent for the free demo.

## `minScore` (type: `integer`):

The field that decides what you pay: company contacts scoring below this are discarded and <b>not charged</b>. The score is contact quality: an ok address on the company's own domain in your preferred role on a sure website scores 80–100; only a risky or free-mail address 30–60. Companies with no usable address are never charged, whatever this says.

## `maxQualified` (type: `integer`):

Hard cap on results — and the ceiling of what <b>this Actor</b> charges: at most this many × $0.02 with AI on (× $0.0075 with AI off), e.g. 100 × $0.02 = $2.00 plus AI tokens. The best contacts are delivered first; the rest are counted, not charged. Affects what you pay.

## `maxDiscoveryChargeUsd` (type: `number`):

Only used when Google or a company's site refuses this Actor: <code>apify/google-search-scraper</code> (website) or <code>vdrmota/contact-info-scraper</code> (contacts) then runs for those companies on your account, capped here — $0.50 in the form and for an API or agent call that leaves it out. Normal runs read everything themselves and spend nothing here. Affects what you pay.

## `enableAi` (type: `boolean`):

Picks the right same-name website, the named people, the address to write to and your first line. <b>On = $0.02 per company contact + AI tokens; off = $0.0075</b>. Needs Apify's model access (paid plans) or your own Gemini / Groq key (section 4). Apify's model access: not measured on the platform yet (dated 2026-10-30).

## `companiesFileUrl` (type: `string`):

A link to a .csv / .xlsx file or a Google Sheet shared 'anyone with the link': the columns <code>name</code> / <code>company</code>, <code>country</code>, <code>website</code> / <code>domain</code>, <code>city</code> are found by their header (CRM exports work as they are). Added to the companies of section 1. Affects what you pay: each company with a checked contact. Runs on any Apify plan — a plan that cannot run Store Actors only skips the fallback.

## `listPageUrl` (type: `string`):

An exhibitor list or member directory URL: the websites it links become the companies, or the names on its profile pages. A page behind a login or JavaScript is refused with the reason. Affects what you pay: only companies with a checked contact. Any Apify plan; a plan that cannot run Store Actors only skips the fallback.

## `maxSearchResults` (type: `integer`):

At most this many company websites per line of <b>Find companies by keyword</b> (10 per Google page). Affects what you pay: worst case this × $0.02 per search with AI on.

## `domainOnly` (type: `boolean`):

On: each row is the company's official website with its confidence and evidence — Google's best match, no page read, no e-mails — at <b>$0.002 per website found</b> (event <code>website-found</code>). Off (default): the full company contact. AI and the add-ons are off in this mode. Affects what you pay.

## `preferRoles` (type: `array`):

The address picked as <b>bestEmail</b> is the first of these roles with a checked address (an ok check first, the company's own domain before free-mail). Default: purchasing, export, sales, general.

## `pagesPerSite` (type: `integer`):

API only — hidden on the form. The home page plus up to this many − 1 pages found by link text: contact, imprint / legal, about, team, sales / export. More pages find more named people and take longer; not what you pay.

## `includePhones` (type: `boolean`):

API only — hidden on the form. Phones printed on the company's pages, as E.164 with the country's code (<code>+4940300000</code>), each with the page it was on.

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

API only — hidden on the form. The company's LinkedIn, Facebook, Instagram, X and YouTube pages linked from its own site.

## `skipRoleOnly` (type: `boolean`):

API only — hidden on the form. Off (default): a company whose only addresses are role inboxes (info@, sales@ …) is delivered. On: those are skipped, free.

## `includeNotFound` (type: `boolean`):

Off (default): companies without a website or without a usable address are counted in the run summary only. On: they are delivered as <code>notFound</code> rows with the reason — never charged.

## `derivePersonEmails` (type: `boolean`):

Needs the AI check. For each person named on the team page without a printed address, the address is built from the pattern of a colleague's printed one (m.brandt@ → f.last), MX-checked and labelled <code>pattern-derived</code> — never a guess without that example. <b>$0.01 per derived address</b> (<code>named-person-email</code>). Affects what you pay.

## `verifyMailbox` (type: `boolean`):

On: each delivered company's <b>bestEmail</b> is SMTP-checked by bounceverify on your account ($0.00089 each), then <code>mailboxStatus</code> says valid / invalid / catch_all — <b>$0.002 per checked company here</b> (<code>mailbox-verified</code>). Off (default): the MX check only (the domain takes mail). Needs a plan that runs Store Actors. Affects what you pay.

## `useStoreFallback` (type: `boolean`):

API only — hidden on the form. On (default): for a company whose Google search or website refused this Actor, <code>apify/google-search-scraper</code> or <code>vdrmota/contact-info-scraper</code> runs on your account for that company only, capped by <b>Max fallback spend</b>; the row says so in <code>sourcePath</code>. Off: those companies stay not found. Affects what you pay.

## `targetFlags` (type: `array`):

Only deliver company contacts that have at least one of these flags, and rank those with more of them higher. Leave empty to keep everything. An API call passes the flag names from the README's flag table, e.g. <code>purchasing_contact</code> (<code>purchasingContact</code> works too); an unknown name stops the run at once with the list of valid ones.

## `suppressionList` (type: `array`):

Company names, domains (<code>acme.de</code>) or addresses to never output — your existing customers, say. Skipped before any search and never charged.

## `llmProvider` (type: `string`):

<b>Apify (no keys)</b> — the AI runs through Apify's built-in OpenRouter proxy; tokens are billed to your Apify account at OpenRouter's rates. <b>My own key</b> — use your OpenAI / Anthropic / Gemini / Groq key instead; a free-tier key assesses only a few company contacts per run — expect 1–3 AI checks (2 calls at a time, one after a rate limit, then the 3 borderline company contacts retried one by one) — and the rest keep their rule score; a paid Groq / Gemini key (billing on) assesses every company contact. Own-key pace measured 2026-10-23: ≈ 1.0–11.2 s per company contact (11.2 s on the latest run) with a free google:gemini-3.5-flash-lite key. timeoutSecs = 240 + 30 s × companies (the search plus a rate-limited own key's worst case): 50 companies → 1740, 100 → 3240.

## `llmModel` (type: `string`):

API only — hidden on the form. Leave empty for the default (<code>anthropic/claude-haiku-4.5</code> via Apify; <code>google:gemini-3.5-flash-lite</code> with your own key). Apify mode takes an OpenRouter slug such as <code>openai/gpt-4.1-mini</code>; own-key mode takes <code>provider:model</code>, e.g. <code>anthropic:claude-haiku-4-5-20251001</code>.

## `llmApiKey` (type: `string`):

Required when <b>AI model access</b> is <i>My own API key</i>. Stored encrypted by Apify, never logged.

## `aiCandidateMultiplier` (type: `integer`):

API only — hidden on the form. How many of the best rule-scored company contacts get the AI pass, as a multiple of <b>Max qualified</b>. Higher = more thorough, slower, more tokens.

## `sendAlertsTo` (type: `string`):

Paste one or more URLs, one per line — the service is detected from the address: a Slack or Discord channel webhook, a Teams Workflows or Google Chat space webhook, your Telegram bot's send link (<code>https://api.telegram.org/bot\<token>/sendMessage?chat_id=@yourchannel</code>) or any other https URL (Zapier, Make, n8n, your CRM), which gets the company contacts as JSON. After every run with at least one new company contact, the digest (how many are new, the top 10 with links) is posted there. Never sent for the free demo. Headers, batching and signing: <i>Delivery details (advanced)</i>.

## `dedupeAcrossRuns` (type: `boolean`):

Remembers every company you were charged for, by its domain (in a named key-value store on your account), and skips it in future runs — before any search. Adding companies to the list keeps the memory of the others.

## `dedupeTtlDays` (type: `integer`):

Contacts go stale — about 20–30 % a year. 0 (default) = a delivered company is never delivered or charged again. <b>90</b> = a quarterly CRM refresh, <b>180</b> = twice a year: after that many days the company is looked up again and, with a checked contact, delivered and charged as a new company contact. Affects what you pay.

## `hubspotToken` (type: `string`):

Each delivered company is upserted into HubSpot by its domain, with <b>bestEmail</b> as a contact (upserted by e-mail) associated to it — no Make / n8n. Create a private app with the scopes crm.objects.companies.write and crm.objects.contacts.write. Never used for the free demo. Stored encrypted.

## `historyDatasetName` (type: `string`):

Optional. Type a name (e.g. <code>company-contact-finder-ai-seen-log</code>) and every run appends its new company contacts with the date to that named dataset on your account — one list across months to connect to Google Sheets or your BI tool once. Empty = off. Costs nothing extra.

## `sourceMode` (type: `string`):

The mode that runs = this field, except <code>{}</code> over the API = the free demo. <b>live</b> — the companies of section 1 (or the file of section 3): Google, the companies' own pages and the e-mail check are read by this Actor (any plan). <b>dataset</b> — an Apify dataset of companies (<code>name</code> / <code>companyName</code> / <code>consigneeName</code>, <code>country</code>, <code>website</code>). <b>list</b> — records you paste into <code>itemsList</code>. The mode you choose always runs as chosen; only in the Console do the untouched sample records next to companies you typed switch to the live search.

## `autoSwitchToLive` (type: `boolean`):

API only — hidden on the form. Console runs only: companies typed next to the untouched sample records start the live search (spend-capped; <code>OUTPUT.switchedToLive</code> names them). Over the API the mode you send is always the mode that runs, whatever this says. Off: the sample stays the free demo in the Console too.

## `failOnSourceError` (type: `boolean`):

API only — hidden on the form. Off (default): a run that could load no company ends with <code>OUTPUT.ok: false</code> and the reason. On: the same run ends FAILED, so a schedule's or an API pipeline's failed-run alert fires. Turn it on for every schedule.

## `datasetId` (type: `string`):

Only for <b>dataset</b> mode. Pick the dataset so the Actor is granted read access to it.

## `itemsList` (type: `array`):

Only for <b>list</b> mode. JSON array of objects with at least <code>name</code> and optionally <code>country</code>, <code>website</code>, <code>city</code> — or rows that already carry <code>emails</code> (checked, not crawled again). The prefilled 4 are the free demo's fictional samples (precomputed, labelled <code>sample</code>).

## `discoveryActorId` (type: `string`):

API only — hidden on the form. Runs on your account only with a raw <b>discoveryInput</b> (API) or when a company's site refuses this Actor (<b>Use Store Actors when Google or a site refuses</b>), capped by <b>Max fallback spend</b>. Its page rows are merged per domain and every address is checked here.

## `discoveryInput` (type: `object`):

API only — hidden on the form. Raw input for <code>discoveryActorId</code> (e.g. <code>{"startUrls": \[{"url": "https://acme.de"}]}</code>): the Store scraper reads those sites on your account instead of this Actor's own reader; <code>maxRequestsPerStartUrl</code> defaults to <b>Pages to read per website</b>. The live search runs that Store Actor on your Apify plan — on a plan that cannot, a Console run scores the free sample instead; paste rows into <code>itemsList</code> (<b>list</b> mode, any plan).

## `maxToProcess` (type: `integer`):

API only — hidden on the form. Upper bound on how many companies are looked up in one run (controls run time). Default = 3 × max company contacts.

## `webhookUrl` (type: `string`):

Qualified company contacts are POSTed here as JSON (Zapier, Make, n8n, your CRM). For Google Sheets / Slack you can also use Apify's built-in Integrations tab. Stored encrypted — Zapier / Make hook URLs carry their secret in the path.

## `webhookHeaders` (type: `object`):

API only — hidden on the form. Extra HTTP headers for the webhook, e.g. <code>{"Authorization": "Bearer …"}</code>. Stored encrypted by Apify, never logged.

## `webhookBatchSize` (type: `integer`):

API only — hidden on the form. 1 = one POST per company contact the moment it is ready. Higher = one POST per N company contacts.

## `webhookSecret` (type: `string`):

API only — hidden on the form. Any random string. Every webhook POST then carries <code>X-Signature: sha256=\<HMAC-SHA256 of the raw body with this secret></code>, so your endpoint can verify it came from this Actor. Stored encrypted by Apify, never logged.

## `dedupeStoreName` (type: `string`):

API only — hidden on the form. Key-value store used for cross-run memory. Left at the default, the memory is kept per search (source and search terms): rewording <code>goalDescription</code> keeps it, so a scheduled run never re-delivers what you already have, and another search starts its own list. Running it for several clients on one account, type one name per client.

## `discoveryTimeoutSecs` (type: `integer`):

API only — hidden on the form. How long a Store fallback run may take before its partial results are used — never more than 60 % of the run's time left.

## `slackWebhookUrl` (type: `string`):

API only — hidden on the form, where <code>sendAlertsTo</code> takes it. Slack incoming-webhook URL for the digest.

## `discordWebhookUrl` (type: `string`):

API only — hidden on the form, where <code>sendAlertsTo</code> takes it. Discord channel webhook URL for the digest.

## `teamsWebhookUrl` (type: `string`):

API only — hidden on the form, where <code>sendAlertsTo</code> takes it. Teams Workflows webhook URL for the digest.

## `googleChatWebhookUrl` (type: `string`):

API only — hidden on the form, where <code>sendAlertsTo</code> takes it. Google Chat space webhook URL for the digest.

## `telegramUrl` (type: `string`):

API only — hidden on the form, where <code>sendAlertsTo</code> takes it. The bot's sendMessage link with its chat_id.

## Actor input object example

```json
{
  "preset": "custom",
  "companies": [],
  "minScore": 30,
  "maxQualified": 100,
  "maxDiscoveryChargeUsd": 0.5,
  "enableAi": true,
  "maxSearchResults": 20,
  "domainOnly": false,
  "preferRoles": [
    "purchasing",
    "export",
    "sales",
    "general"
  ],
  "pagesPerSite": 6,
  "includePhones": true,
  "includeSocials": true,
  "skipRoleOnly": false,
  "includeNotFound": false,
  "derivePersonEmails": false,
  "verifyMailbox": false,
  "useStoreFallback": true,
  "llmProvider": "apify",
  "aiCandidateMultiplier": 2,
  "dedupeAcrossRuns": true,
  "dedupeTtlDays": 0,
  "historyDatasetName": "",
  "sourceMode": "list",
  "autoSwitchToLive": true,
  "failOnSourceError": false,
  "itemsList": [
    {
      "name": "Nordhafen Textilhandel GmbH",
      "sample": true,
      "country": "DE",
      "city": "Hamburg",
      "website": "https://www.nordhafen-textilhandel.de/",
      "websiteConfidence": 0.86,
      "websiteEvidence": "domain spells the name (1.00); .de = DE; legal name 'Nordhafen Textilhandel GmbH' on the site; VAT DE000000001 (DE) on the page; Google result #1; skipped europages.de, linkedin.com (directory / marketplace / social)",
      "legalName": "Nordhafen Textilhandel GmbH",
      "vatId": "DE000000001",
      "address": "Am Sandtorkai 12, 20457 Hamburg",
      "employeesHint": "rund 40 Mitarbeiter",
      "emails": [
        {
          "email": "einkauf@nordhafen-textilhandel.de",
          "role": "purchasing",
          "status": "ok",
          "mx": true,
          "disposable": false,
          "isRoleAccount": true,
          "typoSuggestion": null,
          "foundOn": "https://www.nordhafen-textilhandel.de/kontakt"
        },
        {
          "email": "m.brandt@nordhafen-textilhandel.de",
          "role": "person",
          "status": "ok",
          "mx": true,
          "disposable": false,
          "isRoleAccount": false,
          "typoSuggestion": null,
          "foundOn": "https://www.nordhafen-textilhandel.de/team"
        },
        {
          "email": "info@nordhafen-textilhandel.de",
          "role": "general",
          "status": "ok",
          "mx": true,
          "disposable": false,
          "isRoleAccount": true,
          "typoSuggestion": null,
          "foundOn": "https://www.nordhafen-textilhandel.de/impressum"
        }
      ],
      "phones": [
        {
          "number": "+4940300000",
          "foundOn": "https://www.nordhafen-textilhandel.de/kontakt"
        }
      ],
      "contactPageUrl": "https://www.nordhafen-textilhandel.de/kontakt",
      "contactFormUrl": "https://www.nordhafen-textilhandel.de/kontakt",
      "socials": {
        "linkedin": "https://www.linkedin.com/company/nordhafen-textilhandel",
        "facebook": null,
        "instagram": null,
        "x": null,
        "youtube": null
      },
      "sourcePath": "own",
      "teamText": "Unser Team\nMarkus Brandt — Leitung Einkauf — m.brandt@nordhafen-textilhandel.de\nJana Petersen — Vertrieb Export\nWir importieren Baumwoll- und Leinenstoffe aus Portugal, Indien und der Türkei für den deutschen Großhandel.",
      "people": [
        {
          "name": "Markus Brandt",
          "title": "Leitung Einkauf",
          "email": "m.brandt@nordhafen-textilhandel.de",
          "emailSource": "printed"
        },
        {
          "name": "Jana Petersen",
          "title": "Vertrieb Export",
          "email": "j.petersen@nordhafen-textilhandel.de",
          "emailSource": "pattern-derived",
          "pattern": "f.last (sample — from m.brandt@nordhafen-textilhandel.de)"
        }
      ],
      "mailboxStatus": "valid",
      "mailboxReason": "sample — what Check the mailbox itself returns: SMTP mailbox exists"
    },
    {
      "name": "Lusitex Têxteis, Lda",
      "foundBy": "search: textile importers, PT (sample)",
      "sample": true,
      "country": "PT",
      "city": "Porto",
      "website": "https://www.lusitex-texteis.pt/",
      "websiteConfidence": 0.78,
      "websiteEvidence": "domain spells the name (0.85); .pt = PT; name in the page title; Google result #1",
      "legalName": "Lusitex Têxteis, Lda",
      "emails": [
        {
          "email": "comercial@lusitex-texteis.pt",
          "role": "sales",
          "status": "ok",
          "mx": true,
          "disposable": false,
          "isRoleAccount": true,
          "typoSuggestion": null,
          "foundOn": "https://www.lusitex-texteis.pt/contactos"
        },
        {
          "email": "geral@lusitex-texteis.pt",
          "role": "general",
          "status": "ok",
          "mx": true,
          "disposable": false,
          "isRoleAccount": true,
          "typoSuggestion": null,
          "foundOn": "https://www.lusitex-texteis.pt/contactos"
        }
      ],
      "phones": [],
      "contactPageUrl": "https://www.lusitex-texteis.pt/contactos",
      "contactFormUrl": null,
      "socials": {
        "linkedin": null,
        "facebook": "https://www.facebook.com/lusitextexteis",
        "instagram": null,
        "x": null,
        "youtube": null
      },
      "sourcePath": "own",
      "teamText": "Sobre nós\nFabricamos malhas de algodão orgânico em Barcelos desde 1994. Exportamos para Espanha, França e Alemanha."
    },
    {
      "name": "Brightwater Fabrics Ltd",
      "sample": true,
      "country": "GB",
      "city": "Manchester",
      "website": "https://www.brightwaterfabrics.co.uk/",
      "websiteConfidence": 0.64,
      "websiteEvidence": "domain close to the name (0.60); .co.uk = GB; Google result #2; skipped yell.com (directory / marketplace / social)",
      "legalName": "Brightwater Fabrics Ltd",
      "emails": [
        {
          "email": "brightwater.fabrics@gmail.com",
          "role": "general",
          "status": "ok",
          "mx": true,
          "disposable": false,
          "isRoleAccount": false,
          "typoSuggestion": null,
          "foundOn": "https://www.brightwaterfabrics.co.uk/contact-us"
        },
        {
          "email": "sales@brightwaterfabrics.co.uk",
          "role": "sales",
          "status": "risky",
          "mx": false,
          "disposable": false,
          "isRoleAccount": true,
          "typoSuggestion": null,
          "foundOn": "https://www.brightwaterfabrics.co.uk/contact-us"
        }
      ],
      "phones": [
        {
          "number": "+441610000000",
          "foundOn": "https://www.brightwaterfabrics.co.uk/contact-us"
        }
      ],
      "contactPageUrl": "https://www.brightwaterfabrics.co.uk/contact-us",
      "contactFormUrl": "https://www.brightwaterfabrics.co.uk/contact-us",
      "socials": {
        "linkedin": null,
        "facebook": null,
        "instagram": null,
        "x": null,
        "youtube": null
      },
      "sourcePath": "own",
      "teamText": ""
    },
    {
      "name": "Kaveri Weaving Mills",
      "sample": true,
      "country": "IN",
      "city": "Erode",
      "website": "https://www.kaveriweaving.in/",
      "websiteConfidence": 0.71,
      "websiteEvidence": "domain spells the name (0.85); .in = IN; Google result #1",
      "legalName": null,
      "emails": [
        {
          "email": "info@kaveriweaving.in",
          "role": "general",
          "status": "invalid",
          "mx": false,
          "disposable": false,
          "isRoleAccount": true,
          "typoSuggestion": null,
          "foundOn": "https://www.kaveriweaving.in/contact"
        }
      ],
      "phones": [
        {
          "number": "+914240000000",
          "foundOn": "https://www.kaveriweaving.in/contact"
        }
      ],
      "contactPageUrl": "https://www.kaveriweaving.in/contact",
      "contactFormUrl": null,
      "socials": {
        "linkedin": null,
        "facebook": null,
        "instagram": null,
        "x": null,
        "youtube": null
      },
      "sourcePath": "own",
      "teamText": ""
    }
  ],
  "discoveryActorId": "vdrmota/contact-info-scraper",
  "webhookBatchSize": 1,
  "dedupeStoreName": "company-contact-finder-ai-seen",
  "discoveryTimeoutSecs": 3600
}
```

# Actor output Schema

## `qualified` (type: `string`):

All qualified company contacts as JSON, best-scoring first.

## `sheet` (type: `string`):

The same company contacts as a spreadsheet.

## `runSummary` (type: `string`):

JSON record with the funnel (loaded -> filtered -> AI-assessed -> qualified), per-reason skip counts, charged events by type, free-tier company contacts used and remaining, whether a budget limit was reached, webhook delivery counts and the dedupe store size.

# 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": [],
    "maxDiscoveryChargeUsd": 0.5,
    "sourceMode": "list",
    "itemsList": [
        {
            "name": "Nordhafen Textilhandel GmbH",
            "sample": true,
            "country": "DE",
            "city": "Hamburg",
            "website": "https://www.nordhafen-textilhandel.de/",
            "websiteConfidence": 0.86,
            "websiteEvidence": "domain spells the name (1.00); .de = DE; legal name 'Nordhafen Textilhandel GmbH' on the site; VAT DE000000001 (DE) on the page; Google result #1; skipped europages.de, linkedin.com (directory / marketplace / social)",
            "legalName": "Nordhafen Textilhandel GmbH",
            "vatId": "DE000000001",
            "address": "Am Sandtorkai 12, 20457 Hamburg",
            "employeesHint": "rund 40 Mitarbeiter",
            "emails": [
                {
                    "email": "einkauf@nordhafen-textilhandel.de",
                    "role": "purchasing",
                    "status": "ok",
                    "mx": true,
                    "disposable": false,
                    "isRoleAccount": true,
                    "typoSuggestion": null,
                    "foundOn": "https://www.nordhafen-textilhandel.de/kontakt"
                },
                {
                    "email": "m.brandt@nordhafen-textilhandel.de",
                    "role": "person",
                    "status": "ok",
                    "mx": true,
                    "disposable": false,
                    "isRoleAccount": false,
                    "typoSuggestion": null,
                    "foundOn": "https://www.nordhafen-textilhandel.de/team"
                },
                {
                    "email": "info@nordhafen-textilhandel.de",
                    "role": "general",
                    "status": "ok",
                    "mx": true,
                    "disposable": false,
                    "isRoleAccount": true,
                    "typoSuggestion": null,
                    "foundOn": "https://www.nordhafen-textilhandel.de/impressum"
                }
            ],
            "phones": [
                {
                    "number": "+4940300000",
                    "foundOn": "https://www.nordhafen-textilhandel.de/kontakt"
                }
            ],
            "contactPageUrl": "https://www.nordhafen-textilhandel.de/kontakt",
            "contactFormUrl": "https://www.nordhafen-textilhandel.de/kontakt",
            "socials": {
                "linkedin": "https://www.linkedin.com/company/nordhafen-textilhandel",
                "facebook": null,
                "instagram": null,
                "x": null,
                "youtube": null
            },
            "sourcePath": "own",
            "teamText": "Unser Team\nMarkus Brandt — Leitung Einkauf — m.brandt@nordhafen-textilhandel.de\nJana Petersen — Vertrieb Export\nWir importieren Baumwoll- und Leinenstoffe aus Portugal, Indien und der Türkei für den deutschen Großhandel.",
            "people": [
                {
                    "name": "Markus Brandt",
                    "title": "Leitung Einkauf",
                    "email": "m.brandt@nordhafen-textilhandel.de",
                    "emailSource": "printed"
                },
                {
                    "name": "Jana Petersen",
                    "title": "Vertrieb Export",
                    "email": "j.petersen@nordhafen-textilhandel.de",
                    "emailSource": "pattern-derived",
                    "pattern": "f.last (sample — from m.brandt@nordhafen-textilhandel.de)"
                }
            ],
            "mailboxStatus": "valid",
            "mailboxReason": "sample — what Check the mailbox itself returns: SMTP mailbox exists"
        },
        {
            "name": "Lusitex Têxteis, Lda",
            "foundBy": "search: textile importers, PT (sample)",
            "sample": true,
            "country": "PT",
            "city": "Porto",
            "website": "https://www.lusitex-texteis.pt/",
            "websiteConfidence": 0.78,
            "websiteEvidence": "domain spells the name (0.85); .pt = PT; name in the page title; Google result #1",
            "legalName": "Lusitex Têxteis, Lda",
            "emails": [
                {
                    "email": "comercial@lusitex-texteis.pt",
                    "role": "sales",
                    "status": "ok",
                    "mx": true,
                    "disposable": false,
                    "isRoleAccount": true,
                    "typoSuggestion": null,
                    "foundOn": "https://www.lusitex-texteis.pt/contactos"
                },
                {
                    "email": "geral@lusitex-texteis.pt",
                    "role": "general",
                    "status": "ok",
                    "mx": true,
                    "disposable": false,
                    "isRoleAccount": true,
                    "typoSuggestion": null,
                    "foundOn": "https://www.lusitex-texteis.pt/contactos"
                }
            ],
            "phones": [],
            "contactPageUrl": "https://www.lusitex-texteis.pt/contactos",
            "contactFormUrl": null,
            "socials": {
                "linkedin": null,
                "facebook": "https://www.facebook.com/lusitextexteis",
                "instagram": null,
                "x": null,
                "youtube": null
            },
            "sourcePath": "own",
            "teamText": "Sobre nós\nFabricamos malhas de algodão orgânico em Barcelos desde 1994. Exportamos para Espanha, França e Alemanha."
        },
        {
            "name": "Brightwater Fabrics Ltd",
            "sample": true,
            "country": "GB",
            "city": "Manchester",
            "website": "https://www.brightwaterfabrics.co.uk/",
            "websiteConfidence": 0.64,
            "websiteEvidence": "domain close to the name (0.60); .co.uk = GB; Google result #2; skipped yell.com (directory / marketplace / social)",
            "legalName": "Brightwater Fabrics Ltd",
            "emails": [
                {
                    "email": "brightwater.fabrics@gmail.com",
                    "role": "general",
                    "status": "ok",
                    "mx": true,
                    "disposable": false,
                    "isRoleAccount": false,
                    "typoSuggestion": null,
                    "foundOn": "https://www.brightwaterfabrics.co.uk/contact-us"
                },
                {
                    "email": "sales@brightwaterfabrics.co.uk",
                    "role": "sales",
                    "status": "risky",
                    "mx": false,
                    "disposable": false,
                    "isRoleAccount": true,
                    "typoSuggestion": null,
                    "foundOn": "https://www.brightwaterfabrics.co.uk/contact-us"
                }
            ],
            "phones": [
                {
                    "number": "+441610000000",
                    "foundOn": "https://www.brightwaterfabrics.co.uk/contact-us"
                }
            ],
            "contactPageUrl": "https://www.brightwaterfabrics.co.uk/contact-us",
            "contactFormUrl": "https://www.brightwaterfabrics.co.uk/contact-us",
            "socials": {
                "linkedin": null,
                "facebook": null,
                "instagram": null,
                "x": null,
                "youtube": null
            },
            "sourcePath": "own",
            "teamText": ""
        },
        {
            "name": "Kaveri Weaving Mills",
            "sample": true,
            "country": "IN",
            "city": "Erode",
            "website": "https://www.kaveriweaving.in/",
            "websiteConfidence": 0.71,
            "websiteEvidence": "domain spells the name (0.85); .in = IN; Google result #1",
            "legalName": null,
            "emails": [
                {
                    "email": "info@kaveriweaving.in",
                    "role": "general",
                    "status": "invalid",
                    "mx": false,
                    "disposable": false,
                    "isRoleAccount": true,
                    "typoSuggestion": null,
                    "foundOn": "https://www.kaveriweaving.in/contact"
                }
            ],
            "phones": [
                {
                    "number": "+914240000000",
                    "foundOn": "https://www.kaveriweaving.in/contact"
                }
            ],
            "contactPageUrl": "https://www.kaveriweaving.in/contact",
            "contactFormUrl": null,
            "socials": {
                "linkedin": null,
                "facebook": null,
                "instagram": null,
                "x": null,
                "youtube": null
            },
            "sourcePath": "own",
            "teamText": ""
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("rich_minds/company-contact-finder-ai").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": [],
    "maxDiscoveryChargeUsd": 0.5,
    "sourceMode": "list",
    "itemsList": [
        {
            "name": "Nordhafen Textilhandel GmbH",
            "sample": True,
            "country": "DE",
            "city": "Hamburg",
            "website": "https://www.nordhafen-textilhandel.de/",
            "websiteConfidence": 0.86,
            "websiteEvidence": "domain spells the name (1.00); .de = DE; legal name 'Nordhafen Textilhandel GmbH' on the site; VAT DE000000001 (DE) on the page; Google result #1; skipped europages.de, linkedin.com (directory / marketplace / social)",
            "legalName": "Nordhafen Textilhandel GmbH",
            "vatId": "DE000000001",
            "address": "Am Sandtorkai 12, 20457 Hamburg",
            "employeesHint": "rund 40 Mitarbeiter",
            "emails": [
                {
                    "email": "einkauf@nordhafen-textilhandel.de",
                    "role": "purchasing",
                    "status": "ok",
                    "mx": True,
                    "disposable": False,
                    "isRoleAccount": True,
                    "typoSuggestion": None,
                    "foundOn": "https://www.nordhafen-textilhandel.de/kontakt",
                },
                {
                    "email": "m.brandt@nordhafen-textilhandel.de",
                    "role": "person",
                    "status": "ok",
                    "mx": True,
                    "disposable": False,
                    "isRoleAccount": False,
                    "typoSuggestion": None,
                    "foundOn": "https://www.nordhafen-textilhandel.de/team",
                },
                {
                    "email": "info@nordhafen-textilhandel.de",
                    "role": "general",
                    "status": "ok",
                    "mx": True,
                    "disposable": False,
                    "isRoleAccount": True,
                    "typoSuggestion": None,
                    "foundOn": "https://www.nordhafen-textilhandel.de/impressum",
                },
            ],
            "phones": [{
                    "number": "+4940300000",
                    "foundOn": "https://www.nordhafen-textilhandel.de/kontakt",
                }],
            "contactPageUrl": "https://www.nordhafen-textilhandel.de/kontakt",
            "contactFormUrl": "https://www.nordhafen-textilhandel.de/kontakt",
            "socials": {
                "linkedin": "https://www.linkedin.com/company/nordhafen-textilhandel",
                "facebook": None,
                "instagram": None,
                "x": None,
                "youtube": None,
            },
            "sourcePath": "own",
            "teamText": """Unser Team
Markus Brandt — Leitung Einkauf — m.brandt@nordhafen-textilhandel.de
Jana Petersen — Vertrieb Export
Wir importieren Baumwoll- und Leinenstoffe aus Portugal, Indien und der Türkei für den deutschen Großhandel.""",
            "people": [
                {
                    "name": "Markus Brandt",
                    "title": "Leitung Einkauf",
                    "email": "m.brandt@nordhafen-textilhandel.de",
                    "emailSource": "printed",
                },
                {
                    "name": "Jana Petersen",
                    "title": "Vertrieb Export",
                    "email": "j.petersen@nordhafen-textilhandel.de",
                    "emailSource": "pattern-derived",
                    "pattern": "f.last (sample — from m.brandt@nordhafen-textilhandel.de)",
                },
            ],
            "mailboxStatus": "valid",
            "mailboxReason": "sample — what Check the mailbox itself returns: SMTP mailbox exists",
        },
        {
            "name": "Lusitex Têxteis, Lda",
            "foundBy": "search: textile importers, PT (sample)",
            "sample": True,
            "country": "PT",
            "city": "Porto",
            "website": "https://www.lusitex-texteis.pt/",
            "websiteConfidence": 0.78,
            "websiteEvidence": "domain spells the name (0.85); .pt = PT; name in the page title; Google result #1",
            "legalName": "Lusitex Têxteis, Lda",
            "emails": [
                {
                    "email": "comercial@lusitex-texteis.pt",
                    "role": "sales",
                    "status": "ok",
                    "mx": True,
                    "disposable": False,
                    "isRoleAccount": True,
                    "typoSuggestion": None,
                    "foundOn": "https://www.lusitex-texteis.pt/contactos",
                },
                {
                    "email": "geral@lusitex-texteis.pt",
                    "role": "general",
                    "status": "ok",
                    "mx": True,
                    "disposable": False,
                    "isRoleAccount": True,
                    "typoSuggestion": None,
                    "foundOn": "https://www.lusitex-texteis.pt/contactos",
                },
            ],
            "phones": [],
            "contactPageUrl": "https://www.lusitex-texteis.pt/contactos",
            "contactFormUrl": None,
            "socials": {
                "linkedin": None,
                "facebook": "https://www.facebook.com/lusitextexteis",
                "instagram": None,
                "x": None,
                "youtube": None,
            },
            "sourcePath": "own",
            "teamText": """Sobre nós
Fabricamos malhas de algodão orgânico em Barcelos desde 1994. Exportamos para Espanha, França e Alemanha.""",
        },
        {
            "name": "Brightwater Fabrics Ltd",
            "sample": True,
            "country": "GB",
            "city": "Manchester",
            "website": "https://www.brightwaterfabrics.co.uk/",
            "websiteConfidence": 0.64,
            "websiteEvidence": "domain close to the name (0.60); .co.uk = GB; Google result #2; skipped yell.com (directory / marketplace / social)",
            "legalName": "Brightwater Fabrics Ltd",
            "emails": [
                {
                    "email": "brightwater.fabrics@gmail.com",
                    "role": "general",
                    "status": "ok",
                    "mx": True,
                    "disposable": False,
                    "isRoleAccount": False,
                    "typoSuggestion": None,
                    "foundOn": "https://www.brightwaterfabrics.co.uk/contact-us",
                },
                {
                    "email": "sales@brightwaterfabrics.co.uk",
                    "role": "sales",
                    "status": "risky",
                    "mx": False,
                    "disposable": False,
                    "isRoleAccount": True,
                    "typoSuggestion": None,
                    "foundOn": "https://www.brightwaterfabrics.co.uk/contact-us",
                },
            ],
            "phones": [{
                    "number": "+441610000000",
                    "foundOn": "https://www.brightwaterfabrics.co.uk/contact-us",
                }],
            "contactPageUrl": "https://www.brightwaterfabrics.co.uk/contact-us",
            "contactFormUrl": "https://www.brightwaterfabrics.co.uk/contact-us",
            "socials": {
                "linkedin": None,
                "facebook": None,
                "instagram": None,
                "x": None,
                "youtube": None,
            },
            "sourcePath": "own",
            "teamText": "",
        },
        {
            "name": "Kaveri Weaving Mills",
            "sample": True,
            "country": "IN",
            "city": "Erode",
            "website": "https://www.kaveriweaving.in/",
            "websiteConfidence": 0.71,
            "websiteEvidence": "domain spells the name (0.85); .in = IN; Google result #1",
            "legalName": None,
            "emails": [{
                    "email": "info@kaveriweaving.in",
                    "role": "general",
                    "status": "invalid",
                    "mx": False,
                    "disposable": False,
                    "isRoleAccount": True,
                    "typoSuggestion": None,
                    "foundOn": "https://www.kaveriweaving.in/contact",
                }],
            "phones": [{
                    "number": "+914240000000",
                    "foundOn": "https://www.kaveriweaving.in/contact",
                }],
            "contactPageUrl": "https://www.kaveriweaving.in/contact",
            "contactFormUrl": None,
            "socials": {
                "linkedin": None,
                "facebook": None,
                "instagram": None,
                "x": None,
                "youtube": None,
            },
            "sourcePath": "own",
            "teamText": "",
        },
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("rich_minds/company-contact-finder-ai").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": [],
  "maxDiscoveryChargeUsd": 0.5,
  "sourceMode": "list",
  "itemsList": [
    {
      "name": "Nordhafen Textilhandel GmbH",
      "sample": true,
      "country": "DE",
      "city": "Hamburg",
      "website": "https://www.nordhafen-textilhandel.de/",
      "websiteConfidence": 0.86,
      "websiteEvidence": "domain spells the name (1.00); .de = DE; legal name '\''Nordhafen Textilhandel GmbH'\'' on the site; VAT DE000000001 (DE) on the page; Google result #1; skipped europages.de, linkedin.com (directory / marketplace / social)",
      "legalName": "Nordhafen Textilhandel GmbH",
      "vatId": "DE000000001",
      "address": "Am Sandtorkai 12, 20457 Hamburg",
      "employeesHint": "rund 40 Mitarbeiter",
      "emails": [
        {
          "email": "einkauf@nordhafen-textilhandel.de",
          "role": "purchasing",
          "status": "ok",
          "mx": true,
          "disposable": false,
          "isRoleAccount": true,
          "typoSuggestion": null,
          "foundOn": "https://www.nordhafen-textilhandel.de/kontakt"
        },
        {
          "email": "m.brandt@nordhafen-textilhandel.de",
          "role": "person",
          "status": "ok",
          "mx": true,
          "disposable": false,
          "isRoleAccount": false,
          "typoSuggestion": null,
          "foundOn": "https://www.nordhafen-textilhandel.de/team"
        },
        {
          "email": "info@nordhafen-textilhandel.de",
          "role": "general",
          "status": "ok",
          "mx": true,
          "disposable": false,
          "isRoleAccount": true,
          "typoSuggestion": null,
          "foundOn": "https://www.nordhafen-textilhandel.de/impressum"
        }
      ],
      "phones": [
        {
          "number": "+4940300000",
          "foundOn": "https://www.nordhafen-textilhandel.de/kontakt"
        }
      ],
      "contactPageUrl": "https://www.nordhafen-textilhandel.de/kontakt",
      "contactFormUrl": "https://www.nordhafen-textilhandel.de/kontakt",
      "socials": {
        "linkedin": "https://www.linkedin.com/company/nordhafen-textilhandel",
        "facebook": null,
        "instagram": null,
        "x": null,
        "youtube": null
      },
      "sourcePath": "own",
      "teamText": "Unser Team\\nMarkus Brandt — Leitung Einkauf — m.brandt@nordhafen-textilhandel.de\\nJana Petersen — Vertrieb Export\\nWir importieren Baumwoll- und Leinenstoffe aus Portugal, Indien und der Türkei für den deutschen Großhandel.",
      "people": [
        {
          "name": "Markus Brandt",
          "title": "Leitung Einkauf",
          "email": "m.brandt@nordhafen-textilhandel.de",
          "emailSource": "printed"
        },
        {
          "name": "Jana Petersen",
          "title": "Vertrieb Export",
          "email": "j.petersen@nordhafen-textilhandel.de",
          "emailSource": "pattern-derived",
          "pattern": "f.last (sample — from m.brandt@nordhafen-textilhandel.de)"
        }
      ],
      "mailboxStatus": "valid",
      "mailboxReason": "sample — what Check the mailbox itself returns: SMTP mailbox exists"
    },
    {
      "name": "Lusitex Têxteis, Lda",
      "foundBy": "search: textile importers, PT (sample)",
      "sample": true,
      "country": "PT",
      "city": "Porto",
      "website": "https://www.lusitex-texteis.pt/",
      "websiteConfidence": 0.78,
      "websiteEvidence": "domain spells the name (0.85); .pt = PT; name in the page title; Google result #1",
      "legalName": "Lusitex Têxteis, Lda",
      "emails": [
        {
          "email": "comercial@lusitex-texteis.pt",
          "role": "sales",
          "status": "ok",
          "mx": true,
          "disposable": false,
          "isRoleAccount": true,
          "typoSuggestion": null,
          "foundOn": "https://www.lusitex-texteis.pt/contactos"
        },
        {
          "email": "geral@lusitex-texteis.pt",
          "role": "general",
          "status": "ok",
          "mx": true,
          "disposable": false,
          "isRoleAccount": true,
          "typoSuggestion": null,
          "foundOn": "https://www.lusitex-texteis.pt/contactos"
        }
      ],
      "phones": [],
      "contactPageUrl": "https://www.lusitex-texteis.pt/contactos",
      "contactFormUrl": null,
      "socials": {
        "linkedin": null,
        "facebook": "https://www.facebook.com/lusitextexteis",
        "instagram": null,
        "x": null,
        "youtube": null
      },
      "sourcePath": "own",
      "teamText": "Sobre nós\\nFabricamos malhas de algodão orgânico em Barcelos desde 1994. Exportamos para Espanha, França e Alemanha."
    },
    {
      "name": "Brightwater Fabrics Ltd",
      "sample": true,
      "country": "GB",
      "city": "Manchester",
      "website": "https://www.brightwaterfabrics.co.uk/",
      "websiteConfidence": 0.64,
      "websiteEvidence": "domain close to the name (0.60); .co.uk = GB; Google result #2; skipped yell.com (directory / marketplace / social)",
      "legalName": "Brightwater Fabrics Ltd",
      "emails": [
        {
          "email": "brightwater.fabrics@gmail.com",
          "role": "general",
          "status": "ok",
          "mx": true,
          "disposable": false,
          "isRoleAccount": false,
          "typoSuggestion": null,
          "foundOn": "https://www.brightwaterfabrics.co.uk/contact-us"
        },
        {
          "email": "sales@brightwaterfabrics.co.uk",
          "role": "sales",
          "status": "risky",
          "mx": false,
          "disposable": false,
          "isRoleAccount": true,
          "typoSuggestion": null,
          "foundOn": "https://www.brightwaterfabrics.co.uk/contact-us"
        }
      ],
      "phones": [
        {
          "number": "+441610000000",
          "foundOn": "https://www.brightwaterfabrics.co.uk/contact-us"
        }
      ],
      "contactPageUrl": "https://www.brightwaterfabrics.co.uk/contact-us",
      "contactFormUrl": "https://www.brightwaterfabrics.co.uk/contact-us",
      "socials": {
        "linkedin": null,
        "facebook": null,
        "instagram": null,
        "x": null,
        "youtube": null
      },
      "sourcePath": "own",
      "teamText": ""
    },
    {
      "name": "Kaveri Weaving Mills",
      "sample": true,
      "country": "IN",
      "city": "Erode",
      "website": "https://www.kaveriweaving.in/",
      "websiteConfidence": 0.71,
      "websiteEvidence": "domain spells the name (0.85); .in = IN; Google result #1",
      "legalName": null,
      "emails": [
        {
          "email": "info@kaveriweaving.in",
          "role": "general",
          "status": "invalid",
          "mx": false,
          "disposable": false,
          "isRoleAccount": true,
          "typoSuggestion": null,
          "foundOn": "https://www.kaveriweaving.in/contact"
        }
      ],
      "phones": [
        {
          "number": "+914240000000",
          "foundOn": "https://www.kaveriweaving.in/contact"
        }
      ],
      "contactPageUrl": "https://www.kaveriweaving.in/contact",
      "contactFormUrl": null,
      "socials": {
        "linkedin": null,
        "facebook": null,
        "instagram": null,
        "x": null,
        "youtube": null
      },
      "sourcePath": "own",
      "teamText": ""
    }
  ]
}' |
apify call rich_minds/company-contact-finder-ai --silent --output-dataset

```

## MCP server setup

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

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/ZMzUD2P9T0EeQHZEQ/builds/IbdLGwZBpk1IwWzeu/openapi.json
