# Company Contact Channels: Role Emails, Socials (`conserving_celerytop/company-contact-channels`) Actor

$4 per 1,000 websites ($3 on Gold). Get each company's role emails (info@, sales@, support@, press@), its own LinkedIn, X, Facebook, Instagram, YouTube, GitHub and TikTok pages, and its contact form, from its website. Personal addresses are left out. No login.

- **URL**: https://apify.com/conserving_celerytop/company-contact-channels.md
- **Developed by:** [Don Mangu](https://apify.com/conserving_celerytop) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 company website checkeds

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/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 Channels: role emails and social profiles from company websites

Company Contact Channels is a contact details scraper for B2B lists. Give it company websites and it returns each company's **role contact channels**: role emails such as info@, sales@, support@, press@ and careers@, the company's own LinkedIn, X, Facebook, Instagram, YouTube, GitHub and TikTok pages, the contact form page, and (if you turn it on) the main phone number. Addresses and profiles of individual people are left out, so the output is ready for outreach, CRM enrichment and routing without personal data to clean up.

### What you get for each company website

| Field | Example |
|---|---|
| `primaryEmail` | `sales@acme.com` |
| `roleEmails` | every role address with its type (general, sales, support, press, careers, privacy, legal, billing and more), whether it is on the company domain, and the page it was on |
| `emailOnDomain` | `true` when a role address is on the company's own domain, `false` when it is only a Gmail or similar address |
| `linkedinUrl`, `xUrl`, `facebookUrl`, `instagramUrl`, `youtubeUrl`, `githubUrl`, `tiktokUrl` | the company's own profiles only, never share buttons, single posts or employees' profiles |
| `contactFormUrl` | the page with the contact form (newsletter and search boxes do not count) |
| `mainPhone` | the switchboard number, only when you turn on Main phone and the site clearly shows one |
| `companyName`, `status`, `pagesChecked` | the company's name when the site states it, whether the site was read, and how many pages |

### How to use it

1. Open the Actor and paste your company websites into **Websites**, one per line. Domains (`acme.com`), full links (`https://www.acme.com/pricing`) and even email addresses (`jane@acme.com`, its domain is used) all work.
2. Turn on **Main phone** if you want the switchboard number.
3. Click **Start**. Each website takes a few seconds; the table fills as sites finish.
4. Download the results as CSV, Excel or JSON, or pull them with the Apify API. The **Overview** view has one row per company; the **Role emails** view lists every address.

The Actor reads the homepage and up to four standard pages linked from it (contact, imprint, about, privacy, press). It follows each site's robots.txt, reads the pages of one site one after another, and reads only a few sites at a time.

### How much does it cost?

**$4.00 per 1,000 websites** ($0.004 per website) on Apify's Free and Starter plans, $3.50 per 1,000 on Scale and $3.00 per 1,000 on Business, charged only when the homepage loads. The price is the same whether the site has one role email or twenty, and it covers all the pages read for that site.

Free: invalid entries, duplicates, sites that block automated visitors, sites whose robots.txt disallows the homepage, and sites that cannot be reached.

Worked example: a list of 2,000 company domains where 1,850 load costs 1,850 x $0.004 = **$7.40** on the Free or Starter plan ($5.55 on Business). The 150 that did not load are free and show their reason in `status`.

Set a spending limit in the run options if you want a hard cap; the run stops cleanly when it is reached.

### Input example

```json
{
    "websites": ["apify.com", "crawlee.dev", "pypi.org"],
    "includeMainPhone": false,
    "maxWebsites": 100
}
```

### Output example

```json
{
    "inputUrl": "northwind-analytics.example",
    "domain": "northwind-analytics.example",
    "companyName": "Northwind Analytics",
    "primaryEmail": "hello@northwind-analytics.example",
    "roleEmails": [
        { "email": "hello@northwind-analytics.example", "type": "general", "onDomain": true, "foundOn": "https://northwind-analytics.example/" },
        { "email": "sales@northwind-analytics.example", "type": "sales", "onDomain": true, "foundOn": "https://northwind-analytics.example/contact" },
        { "email": "press@northwind-analytics.example", "type": "press", "onDomain": true, "foundOn": "https://northwind-analytics.example/contact" }
    ],
    "emailOnDomain": true,
    "linkedinUrl": "https://www.linkedin.com/company/northwind-analytics",
    "xUrl": "https://x.com/NorthwindHQ",
    "facebookUrl": null,
    "instagramUrl": null,
    "youtubeUrl": "https://www.youtube.com/@northwindanalytics",
    "githubUrl": "https://github.com/northwind-analytics",
    "tiktokUrl": null,
    "contactFormUrl": "https://northwind-analytics.example/contact",
    "contactPageUrl": "https://northwind-analytics.example/contact",
    "mainPhone": null,
    "pagesChecked": 5,
    "status": "ok",
    "charged": true
}
```

The example company is made up (the .example domain is reserved for examples). The dataset also has `pageUrls`, `nonRoleEmailsSkipped`, `finalUrl`, `checkedAt` and `error`.

### Why role channels only?

Role addresses belong to a team, not a person. They stay valid when people change jobs, they reach whoever handles that function, and under GDPR and similar laws they usually carry less risk than a named employee's address. The Actor never saves a personal address. It only counts how many it left out, in `nonRoleEmailsSkipped`.

### Bulk lists

Use a long list of company websites from an Apify Dataset or from a file. Pick the Dataset under **Dataset with the list** and write the name of its field under **Field in the dataset**. Leave the field name empty to use the first text field. Or paste the web address of a .txt, .csv or .json file under **List file URL**. A .csv file uses its first column. A header row is skipped. The file can be up to 10 MB. Entries from the Dataset and the file are added to the ones typed under **Websites**, and duplicates are removed. The limit of 10,000 websites per run and the **Maximum websites** setting cover the whole list. The price per website does not change.

### Related Actors

- [Tech Jobs Search](https://apify.com/conserving_celerytop/tech-jobs-search): the newest matching jobs across hundreds of tech companies.
- [ATS Jobs API](https://apify.com/conserving_celerytop/live-career-page-jobs-api): every open job of the companies you list, read live from their job boards.

### FAQ

**Is it legal to collect this data?**
The Actor reads public pages only, with no login, follows robots.txt, and returns company contact channels that the company publishes for people to use. It does not collect personal data. You are still responsible for how you use the results, for example the anti-spam rules for cold email in your country.

**Why is a field empty?**
The site does not show that channel on the pages that were read, or it is not clearly the company's own (for example a partner's profile mentioned in a blog post). Raise **Pages per website** if a site keeps its details deeper. Sites that build their pages with JavaScript only may show few details.

**Why did a website return `blocked`?**
Some sites answer automated visitors with a challenge page or an access-denied error. The Actor does not try to get around that; the row is free.

**Why is `mainPhone` empty when the site has a phone number?**
It is returned only when the site clearly presents it as the company's main line. Fax, mobile and direct numbers, numbers next to a person's name, and lists of several office numbers are left out on purpose.

**Can I find a specific person's email?**
No. This Actor is built for company role channels and never returns personal addresses.

**How many websites can I check in one run?**
Up to 10,000. Plan on roughly an hour per 1,000 websites at the default settings; more memory makes it faster.

**Is this affiliated with LinkedIn, X, Meta, YouTube, GitHub or TikTok?**
No. The Actor only reads the company's own website and reports the profile links the company publishes there. It does not visit or scrape those networks.

# Actor input Schema

## `websites` (type: `array`):

Company websites or domains, one per line, such as acme.com or https://www.acme.com. An email address such as info@acme.com also works: its domain is used. Up to 10,000.

## `listDatasetId` (type: `string`):

Pick an Apify Dataset that holds your company websites, one entry per item. They are added to the entries typed above.

## `listDatasetField` (type: `string`):

Name of the dataset field that holds the entry. Leave empty to use the first text field it finds.

## `listFileUrl` (type: `string`):

Web address of a .txt, .csv or .json file with your company websites, one entry per line. A header row is skipped. Up to 10 MB.

## `maxWebsites` (type: `integer`):

Stop after this many websites from your list.

## `includeMainPhone` (type: `boolean`):

Add the company's main switchboard number when the site clearly shows it as its main line. Fax, mobile and direct lines, and numbers next to a person's name, are never returned. When a site lists several office numbers with none leading, the field stays empty.

## `maxPagesPerWebsite` (type: `integer`):

Pages read per website, homepage included. The Actor picks the contact, imprint, about, privacy and press pages linked from the homepage, in that order. The price per website stays the same.

## `maxConcurrency` (type: `integer`):

Websites read at the same time. Pages of one website are always read one after another.

## Actor input object example

```json
{
  "websites": [
    "apify.com",
    "crawlee.dev",
    "pypi.org"
  ],
  "maxWebsites": 100,
  "includeMainPhone": false,
  "maxPagesPerWebsite": 5,
  "maxConcurrency": 3
}
```

# Actor output Schema

## `overview` (type: `string`):

inputUrl, companyName, primaryEmail, emailOnDomain, linkedinUrl, xUrl, facebookUrl, instagramUrl, youtubeUrl, githubUrl, tiktokUrl, contactFormUrl, mainPhone and status. The dataset also has roleEmails, contactPageUrl, pageUrls and more.

## `emails` (type: `string`):

Every role address per website with its type, onDomain and the page it was found on.

## `stats` (type: `string`):

Websites read and charged, pages read, websites with a role email, a social profile, a contact form or a main phone, and statuses.

# 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 = {
    "websites": [
        "apify.com",
        "crawlee.dev",
        "pypi.org"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("conserving_celerytop/company-contact-channels").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 = { "websites": [
        "apify.com",
        "crawlee.dev",
        "pypi.org",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("conserving_celerytop/company-contact-channels").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 '{
  "websites": [
    "apify.com",
    "crawlee.dev",
    "pypi.org"
  ]
}' |
apify call conserving_celerytop/company-contact-channels --silent --output-dataset

```

## MCP server setup

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

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/6tdKSNVprCQ5893RR/builds/PbOwJR7y2ItZcjtlG/openapi.json
