# Logo & Favicon Extractor: Company Logos from a List or CSV (`nerolabs/logo-favicon-finder`) Actor

Returns each website's logo, best icon (apple-touch, manifest) and favicon, with real size and format, plus site name and brand colour. Input: websites list, dataset, CSV or Google Sheet (columns kept). $0.002 per site found; failures free. Agent-ready via x402 and MCP.

- **URL**: https://apify.com/nerolabs/logo-favicon-finder.md
- **Developed by:** [Adam Pearce](https://apify.com/nerolabs) (community)
- **Categories:** Lead generation, Developer tools, Agents
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.40 / 1,000 website founds

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

## Logo & Favicon Extractor: Company Logos from a List or CSV

**Give it a list of websites. Get back each company's logo, its best square icon and its favicon, as working image links with their real size and format.**

Building a CRM, a directory, a comparison page or a lead list and need a logo next to every company? Since Clearbit's free logo service was switched off, that usually means hunting through each site by hand. This does it for the whole list in one run: paste websites, or point it at an Apify dataset, a CSV, an Excel file or a Google Sheet, and every row comes back with its original columns plus the logo columns.

**$0.002 per website where something is found** ($2 per 1,000). Sites that can't be read or have nothing usable are free.

### What you get for each website

| Column | What it is |
|---|---|
| `logoUrl` | The company's own logo file: from its structured data (schema.org), or the image in its header's home link |
| `logoFormat`, `logoWidth`, `logoHeight` | Measured from the downloaded file (svg, png, webp, jpeg...), not read from the HTML |
| `iconUrl` | The best square icon, largest first: apple-touch-icon, web app manifest icon or favicon |
| `iconWidth`, `iconHeight`, `iconFormat` | Measured, so you can drop anything too small for your layout |
| `faviconUrl` | The classic small browser icon |
| `siteName` | The brand name the site declares (or its page title) |
| `themeColor` | The brand colour the site declares for browsers, when it has one |
| `ogImageUrl` | The social share image, kept separate because it is a banner, not a logo |
| `storedLogoUrl`, `storedIconUrl` | Your own copy of each image, if you switch on "Save a copy" (no extra charge) |
| `status`, `statusDetail` | `ok`, or a plain reason why not (blocked, unreachable, robots.txt, nothing found...) |

**Every image link is checked.** Each logo and icon is downloaded and confirmed to be a real image before it is returned, so you never get a link that turns out to be a "not found" page. Broken candidates are skipped and the next one is tried.

### Example

Input: `websites: ["stripe.com", "https://www.ikea.com", "notion.so", "github.com"]`

| website | siteName | logoUrl | logo size | iconUrl | icon size |
|---|---|---|---|---|---|
| stripe.com | Stripe | ...stripeassets.com/.../favicon.svg | svg 512x512 | .../apple-touch-icon.png | 180x180 |
| ikea.com | IKEA | https://www.ikea.com/global/assets/logos/brand/ikea.svg | svg 98x40 | .../favicon.ico | 48x48 |
| notion.so | Notion | https://www.notion.com/front-static/logo-ios.png | png 512x512 | .../apple-touch-icon.png | 512x512 |
| github.com | GitHub | (none: drawn as inline SVG) | | .../manifest icon | 512x512 |

When a site draws its logo as inline code (GitHub, Airbnb, The Guardian) there is no logo file to link to; `logoIsInlineSvg` says so and the best icon is still returned.

### Input

- **Websites**: type or paste websites or bare domains, one per line.
- **Dataset**: the output of any Google Maps, directory or lead scraper. The website column is found automatically (`website`, `domain`, `url`, `homepage`...).
- **File or Google Sheet URL**: a public CSV, Excel, JSON file, or a Google Sheet shared as "Anyone with the link can view".

Options: keep only found rows or only problems, save a copy of every image into the run's storage, list every icon the site declares, export CSV or Excel, append to a named dataset.

### What it costs

| Event | Price |
|---|---|
| Website where a logo or icon was found | $0.002 |
| CSV or Excel export file | $0.01 |

1,000 websites cost about **$2**. Unreachable, blocked, robots.txt-refused, duplicate and invalid rows, and sites with nothing usable, are **not charged**. If the home page is blocked but the site's icon is at its standard address, you get the icon and that row is charged once.

### Good to know

- **Robots.txt is respected by default.** A site that asks tools not to read its home page is skipped (not charged).
- **Logos are trademarks.** This Actor tells you where each company publishes its own logo. Whether you may display it is between you and the owner.
- **No browser, no proxy needed** for most sites, which is why it is fast and cheap. An optional proxy is there for sites that block by country.

### For AI agents and automations

Pay per event, no subscription, callable through the Apify API, MCP (`nerolabs/logo-favicon-finder`) and x402. Send `{"websites": ["stripe.com"]}` and read `logoUrl` and `iconUrl` from the dataset.

### The rest of the toolkit

Pair it with [Website Contact Finder](https://apify.com/nerolabs/website-contact-finder) and [Domain Availability Checker & WHOIS](https://apify.com/nerolabs/domain-whois-checker) on the same list, then shape the result with [Dataset Filter & Transform](https://apify.com/nerolabs/dataset-filter-transform), [Merge Datasets & Remove Duplicates](https://apify.com/nerolabs/dataset-merge-dedupe) or [Dataset Cleaner & Exporter](https://apify.com/nerolabs/dataset-cleaner-exporter).

***

If this saved you hunting for logos one site at a time, a review on the Store page helps a lot. If something looks wrong, open an issue on the Issues tab and I will answer personally.

# Actor input Schema

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

Websites or domains, one per line (stripe.com or https://stripe.com). Leave empty to read a dataset, a file or a Google Sheet instead.

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

An Apify dataset, for example the output of a Google Maps, directory or lead scraper. Every original column comes back with the logo columns added.

## `fileUrl` (type: `string`):

A public link to a CSV, TSV, Excel, JSON or JSON Lines file with one row per website. A normal Google Sheets link works: share it as 'Anyone with the link can view'. Used when no dataset is given.

## `fileFormat` (type: `string`):

Leave on 'Detect automatically' unless the link has no file extension and the server reports the wrong content type.

## `sheetName` (type: `string`):

Which sheet to read from an Excel workbook. Defaults to the first sheet.

## `data` (type: `array`):

Rows as inline JSON, an alternative to a dataset or file. Each object needs a field holding the website.

## `websiteField` (type: `string`):

The column that holds the website or domain. Leave empty to detect it (website, domain, url, homepage...).

## `storeImages` (type: `boolean`):

Also downloads each found logo and icon into this run's key-value store and returns a stable link (storedLogoUrl, storedIconUrl), so your app does not hotlink the website. No extra charge.

## `includeAllIcons` (type: `boolean`):

Adds allIcons: every icon link the page and its web app manifest declare, largest first (not each one downloaded).

## `keep` (type: `string`):

Filter the output. Filtering does not change the price: only found sites are ever charged.

## `keepOriginalFields` (type: `boolean`):

Return every input column alongside the new ones.

## `respectRobotsTxt` (type: `boolean`):

Skip sites whose robots.txt asks automated tools not to read the home page (not charged).

## `proxyConfiguration` (type: `object`):

Optional. Off by default; most sites answer directly.

## `concurrency` (type: `integer`):

How many websites to check in parallel.

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

How long to wait for a page or image.

## `maxItems` (type: `integer`):

Stop after this many input rows.

## `exportFormats` (type: `array`):

Also write the results as a downloadable CSV or Excel file, linked from the run's output. $0.01 per file, charged only when at least one website was found.

## `outputDatasetName` (type: `string`):

Also append every kept row to a named dataset that persists across runs. Not charged again.

## Actor input object example

```json
{
  "websites": [
    "https://apify.com",
    "stripe.com",
    "https://www.patagonia.com",
    "notion.so"
  ],
  "fileFormat": "auto",
  "storeImages": false,
  "includeAllIcons": false,
  "keep": "all",
  "keepOriginalFields": true,
  "respectRobotsTxt": true,
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "concurrency": 10,
  "requestTimeoutSecs": 20,
  "exportFormats": []
}
```

# Actor output Schema

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

Every original row with logo, icon and favicon links, their measured size and format, site name and brand colour.

## `summary` (type: `string`):

Websites found, logos and icons found, status counts, export links and warnings.

# 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": [
        "https://apify.com",
        "stripe.com",
        "https://www.patagonia.com",
        "notion.so"
    ]
};

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

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

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

```

## Python example

```python
from apify_client import ApifyClient

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

# Prepare the Actor input
run_input = { "websites": [
        "https://apify.com",
        "stripe.com",
        "https://www.patagonia.com",
        "notion.so",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("nerolabs/logo-favicon-finder").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "websites": [
    "https://apify.com",
    "stripe.com",
    "https://www.patagonia.com",
    "notion.so"
  ]
}' |
apify call nerolabs/logo-favicon-finder --silent --output-dataset

```

## MCP server setup

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

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

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/wzyDYtJeK5GBdnWBh/builds/IDjmlxlZLJh5a2c0V/openapi.json
