# Company Public Info Scraper (`mrlarry/company-public-info-scraper`) Actor

Finds a company's official website and public social media profiles (Facebook, X/Twitter, LinkedIn, Instagram, YouTube, TikTok)

- **URL**: https://apify.com/mrlarry/company-public-info-scraper.md
- **Developed by:** [Kaspars Bekmanis](https://apify.com/mrlarry) (community)
- **Categories:** Developer tools, Lead generation, Social media
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $40.00 / 1,000 results

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

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

## How to integrate an Actor?

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

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

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

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

# README

## Company Website & Social Media Finder — Company Info Scraper API

**Find any company's official website, social media profiles, and contact e-mails
from just its name.** A fast, no-code lead enrichment and company data scraper for
sales prospecting, B2B lead generation, competitor research, recruiting, investment
due diligence, and OSINT — usable by humans in [Apify Console](https://console.apify.com/)
or called programmatically by scripts and **AI agents** (via the Apify API or MCP).

Give it a company name like `"Apify"` or `"Nike"` and get back, as clean JSON:

- ✅ Official **website URL**
- ✅ Page **title** and **meta description**
- ✅ **Social media links** — Facebook, X/Twitter, LinkedIn, Instagram, YouTube, TikTok
- ✅ Public **contact e-mail addresses**

No API keys to configure, no proxies to set up — just run it with a company name.

### Who uses a company info scraper like this?

- **Sales & SDR teams** — enrich a lead list with a company's website and social
  profiles before outreach.
- **Marketing / lead generation** — build prospect lists with verified company links
  instead of manually Googling each one.
- **Recruiters** — quickly find a company's LinkedIn page and site when researching
  a candidate's employer.
- **Investors & analysts** — pull a quick public-info snapshot on a company for due
  diligence or competitor tracking.
- **Journalists & OSINT researchers** — find a company's public footprint fast.
- **AI agents & automation pipelines** — a simple, structured tool an LLM agent can
  call to "look up a company" without needing its own scraping logic.

### What it does

1. **Input** — a company name (e.g. `"Apify"`), or a website URL if you already know it.
2. **Search** — if no URL was given, it searches the web for the company's likely
   official website.
3. **Scrape** — fetches the homepage and extracts:
   - page title
   - meta / OpenGraph description
   - social media profile links
   - public contact e-mail addresses (from `mailto:` links and page text)
4. **Output** — one JSON record per run, pushed to the Actor's default dataset.

The Actor **never crashes**: every network or parsing failure is caught, logged, and
returned as a clear `status: "error"` record instead of an unhandled exception.

### Frequently asked questions

**How do I find a company's official website automatically?**
Run this Actor with the company's name as input (`companyName`). It searches the web,
picks the most plausible official domain, and returns the URL — no manual Googling.

**Can I get a company's social media links from just its name?**
Yes. Once the website is found (or given directly via `websiteUrl`), the Actor scans
the homepage for links to Facebook, X/Twitter, LinkedIn, Instagram, YouTube, and
TikTok and returns whichever profiles it finds.

**Does this work for lead enrichment / bulk company lists?**
Yes — run the Actor once per company name (e.g. from a CSV or spreadsheet via the
Apify API) to enrich a whole lead list with websites and social profiles.

**Can AI agents use this tool?**
Yes. It's a standard Apify Actor with a defined input/output schema, callable via the
[Apify API](https://docs.apify.com/api/v2) or Apify's MCP server — an LLM agent can
call it like any other tool to "look up a company" and get structured JSON back.

**What if the company can't be found?**
The Actor never crashes. If no website or social links are found, it returns a clear
`status: "error"` record with a human-readable `error` message instead of failing
silently or throwing an exception.

**Is this free?**
The Actor itself is billed per use via Apify's Pay-Per-Event pricing (see
[Monetization](#monetization) below) — you only pay for runs and results you get.

### Input

Configured in [`.actor/INPUT_SCHEMA.json`](.actor/INPUT_SCHEMA.json).

| Field                | Type    | Required | Default | Description                                            |
|-----------------------|---------|----------|---------|----------------------------------------------------------|
| `companyName`         | string  | no\*      | —       | Company name to look up.                                 |
| `websiteUrl`          | string  | no\*      | —       | Skip the search step and scrape this URL directly.       |
| `maxRetries`          | integer | no       | `2`     | Retries per failed HTTP request.                          |
| `requestTimeoutSecs`  | integer | no       | `15`    | Timeout (seconds) per HTTP request.                       |

\* At least one of `companyName` or `websiteUrl` must be provided.

Example input:

```json
{
    "companyName": "Apify",
    "maxRetries": 2,
    "requestTimeoutSecs": 15
}
```

### Output

Pushed to the dataset (`Actor.push_data`) — one record per run.

**Success:**

```json
{
    "companyName": "Apify",
    "websiteUrl": "https://apify.com/",
    "title": "Apify: Full-stack web scraping and data extraction platform",
    "description": "Apify is a web scraping and data extraction platform...",
    "socialLinks": {
        "facebook": "https://www.facebook.com/apifytech",
        "twitter": "https://x.com/apify",
        "linkedin": "https://www.linkedin.com/company/apifytechnologies",
        "youtube": "https://www.youtube.com/apify"
    },
    "emails": ["support@apify.com"],
    "status": "success",
    "error": null
}
```

**Failure (e.g. company not found, site unreachable):**

```json
{
    "companyName": "Xyzzy Nonexistent Corp 12345",
    "websiteUrl": null,
    "title": null,
    "description": null,
    "socialLinks": {},
    "emails": [],
    "status": "error",
    "error": "No search results found for company 'Xyzzy Nonexistent Corp 12345'."
}
```

### Project structure

```
asa/
├── .actor/
│   ├── actor.json          # Apify Actor configuration
│   └── INPUT_SCHEMA.json   # Input form definition
├── main.py                 # Actor entry point (Apify SDK for Python)
├── requirements.txt        # requests, beautifulsoup4, lxml, apify
├── Dockerfile              # Build definition used by Apify
├── storage/                # Local run storage (sample INPUT.json included)
└── README.md
```

### Running locally

Requires Python 3.11+ and the [Apify CLI](https://docs.apify.com/cli/) (`npm install -g apify-cli` or `pipx install apify-cli`).

```bash
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

## Uses storage/key_value_stores/default/INPUT.json as input
apify run
```

Without the Apify CLI, you can also run it directly by setting the input via
environment variable:

```bash
export APIFY_INPUT_KEY=INPUT
python main.py
```

Output appears in `storage/datasets/default/`.

### Deploying to Apify

```bash
apify login
apify push
```

This builds the Docker image from the `Dockerfile` and creates/updates the Actor
in your Apify account. From there, publish it to Apify Store from the Apify Console
(**Actor → Publication → Publish to Store**).

### Monetization

This Actor uses Apify's **Pay-Per-Event (PPE)** pricing model via its built-in
**synthetic events** — no charging code needed in `main.py` at all:

| Synthetic event               | Charged when                                    | Suggested price |
|--------------------------------|--------------------------------------------------|------------------|
| `apify-actor-start`            | Automatically, once per run                       | $0.01            |
| `apify-default-dataset-item`   | Automatically, per item pushed to the default dataset (one per run here) | $0.04 |

To activate billing:

1. In [Apify Console](https://console.apify.com/), open the Actor → **Publication →
   Monetization → Set up monetization**.
2. Choose **Pay per event**. Set the price for `apify-actor-start` (e.g. `$0.01`) and
   `apify-default-dataset-item` (e.g. `$0.04`) — total **$0.05 per run** with the
   example prices above. Remove any other empty/unused event rows the form adds.
3. Publish the Actor to Apify Store. Apify handles billing, invoicing and payouts to
   you automatically — you get paid every time a user or an AI agent runs it.

You can test charging locally without real billing:

```bash
ACTOR_TEST_PAY_PER_EVENT=true apify run
```

This logs simulated charges to a local `charging-log` dataset instead of billing anyone.

#### A note on x402 / USDC

Apify Store's own payment rails run on Apify's platform billing (credits/USD via
Pay-Per-Event, pay-per-result, or rental pricing) — **not** on the
[x402](https://www.x402.org/) HTTP-402 stablecoin protocol. If your goal is literal
USDC micropayments settled via x402 (e.g. for direct AI-agent-to-agent payments
outside the Apify Store), that requires exposing this scraper as a standalone HTTP
API wrapped with x402 payment middleware, deployed separately from the Apify Store
listing — the scraping logic in `main.py` (`find_company_website` /
`scrape_website`) is reusable as-is for that, but the Actor/PPE wiring above is
Apify-specific and wouldn't apply. Say the word if you want that standalone x402 API
variant built as a second deployment target.

### Error handling & logging

- All HTTP calls go through `http_get()`, which retries (`maxRetries`) and raises a
  clear `ScrapeError` on final failure — never a raw exception.
- `main()` catches `ScrapeError` and any unexpected `Exception`, logs it via
  `Actor.log` (visible in the Apify Console run log), and still produces a valid
  JSON output record with `status: "error"` and a human-readable `error` message.
- Missing input (`companyName` and `websiteUrl` both empty) fails the run explicitly
  via `Actor.fail()` with a descriptive status message.

### Limitations

- Website discovery relies on parsing DuckDuckGo's HTML search results, which is
  free and keyless but can occasionally be rate-limited or change markup — the
  Actor reports this as a normal `status: "error"` result rather than crashing.
- Only public, unauthenticated pages are accessed. No login-gated data is scraped.

# Actor input Schema

## `companyName` (type: `string`):

The name of the company to look up (e.g. 'Apify' or 'SIA Piemērs'). Leave empty if you provide a websiteUrl directly.

## `websiteUrl` (type: `string`):

If you already know the company's website, provide it here to skip the search step and scrape it directly.

## `maxRetries` (type: `integer`):

How many times to retry a failed HTTP request before giving up.

## `requestTimeoutSecs` (type: `integer`):

Timeout for each HTTP request in seconds.

## Actor input object example

```json
{
  "companyName": "Apify",
  "maxRetries": 2,
  "requestTimeoutSecs": 15
}
```

# 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 = {
    "companyName": "Apify"
};

// Run the Actor and wait for it to finish
const run = await client.actor("mrlarry/company-public-info-scraper").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 = { "companyName": "Apify" }

# Run the Actor and wait for it to finish
run = client.actor("mrlarry/company-public-info-scraper").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "companyName": "Apify"
}' |
apify call mrlarry/company-public-info-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=mrlarry/company-public-info-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/60XaLca8G5g6Z8zFJ/builds/jxpMWgRA1vb5t55Lr/openapi.json
