# Impressum Scraper — DACH Register No., VAT ID & Legal Name (`yugenox/impressum-company-data-extractor`) Actor

Turn German, Austrian and Swiss domains into verified company data from each site's Impressum: legal name and form, address, register court and number (HRB, FN, UID), checksum-checked VAT ID, phone and role mailboxes. One row per domain. Misses are free.

- **URL**: https://apify.com/yugenox/impressum-company-data-extractor.md
- **Developed by:** [Yugenox Corp](https://apify.com/yugenox) (community)
- **Categories:** Lead generation, Business
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.50 / 1,000 company founds

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

## Impressum Scraper — DACH Register No., VAT ID & Legal Name

Turn a list of German, Austrian and Swiss domains into verified company data. For every domain this Actor finds the
website's **Impressum** (legal notice) — the page every German, Austrian and Swiss business website must publish — and
returns the **legal company name and form, address, commercial register court and number, VAT ID (check-digit
verified), business phone and role mailboxes**. One row per domain, ready for your CRM.

**You only pay for companies found.** Domains without an Impressum, websites that refuse the visit, parked domains and
dead links are free.

### What you get

| Field | Example |
|---|---|
| Legal name / form | `sipgate GmbH` / `GmbH` |
| Address | `Gladbacher Straße 74, 40219 Düsseldorf, DE` |
| Register court / number | `Amtsgericht Düsseldorf` / `HRB 39841` |
| VAT ID + checksum check | `DE219349391` ✓ |
| Phone, role mailboxes | `+49 211 635555-0`, `info@sipgate.de` |
| Source page | `https://www.sipgate.de/impressum` |
| Confidence | `high` (score 0–100) |

Works for:

- 🇩🇪 Germany — HRB, HRA, VR (associations), GnR (cooperatives), PR (partnerships), USt-IdNr. `DE…`
- 🇦🇹 Austria — Firmenbuch `FN 123456a`, ZVR (associations), UID `ATU…`
- 🇨🇭 Switzerland / 🇱🇮 Liechtenstein — UID `CHE-123.456.789` (MWST), Handelsregister des Kantons …
- Legal forms such as GmbH, AG, SE, UG (haftungsbeschränkt), GmbH & Co. KG, KGaA, OHG, e.K., e.V., eG, OG, e.U., Sàrl, SA.

### Use cases

- **DACH lead generation** — turn a scraped list of websites into companies with a legal name, address and phone.
- **CRM data quality** — fill in or check legal names, register numbers and VAT IDs for your accounts.
- **KYB / supplier onboarding** — get the register number and VAT ID to look up in the official register.
- **Invoicing and compliance** — collect checksum-valid VAT IDs for B2B invoices.
- **Market mapping** — split a domain list by legal form, city or country.

### How to use it

1. Paste your domains into **Domains or websites** — one per line. Bare domains (`firma.de`), full URLs
   (`https://www.firma.at/de/`) and company e-mail addresses (`info@firma.ch`) all work. A URL that points straight at
   an Impressum page is read directly.
2. Optionally set **Max companies** to stop after a number of found companies.
3. Run it and download the results as Excel, CSV or JSON, or connect them to your CRM with Apify integrations.

#### Input example

```json
{
  "domains": ["sipgate.de", "hetzner.com", "world4you.com"],
  "maxItems": 0,
  "includeRoleEmails": true,
  "includeMisses": true
}
```

| Option | What it does |
|---|---|
| Domains or websites | Domains, URLs or company e-mail addresses. Personal mail providers (gmail.com, gmx.de, web.de …) are skipped. Duplicates are checked once. |
| Max companies | Stop after this many companies were found. 0 = the whole list. |
| Country hint | Only used to tell Austrian and Swiss 4-digit postcodes apart when a page doesn't say. |
| Include role mailboxes | Adds the company's own role mailboxes (info@, kontakt@, office@ …). |
| One row for every domain | Adds a free status row for domains without company data, so every input has a row. |
| Websites at a time | 5–20 different websites side by side (default 10; above 10 needs more run memory — 512 MB for 20). |

### Output example

A real row (from `sipgate.de`, checked 2026-10-29), trimmed:

```json
{
  "domain": "sipgate.de",
  "status": "found",
  "legalName": "sipgate GmbH",
  "legalForm": "GmbH",
  "entityType": "company",
  "street": "Gladbacher Straße 74",
  "postalCode": "40219",
  "city": "Düsseldorf",
  "country": "DE",
  "phone": "+49 211 635555-0",
  "emails": ["info@sipgate.de"],
  "registerCourt": "Amtsgericht Düsseldorf",
  "registerType": "HRB",
  "registerNumber": "HRB 39841",
  "vatId": "DE219349391",
  "vatIdChecksumValid": true,
  "registeredSeat": "Düsseldorf",
  "impressumUrl": "https://www.sipgate.de/impressum",
  "websiteUrl": "https://www.sipgate.de/",
  "foundOn": "impressum",
  "confidence": "high",
  "confidenceScore": 100
}
```

Domains without company data get a free status row (when "One row for every domain" is on), for example
`{"domain": "example-shop.com", "status": "no-impressum", "note": "No Impressum / legal-notice page was found …"}`.
Statuses: `found` (charged) · `no-company-data` · `no-impressum` · `blocked` · `rate-limited` · `disallowed` ·
`unreachable` · `timeout` · `parked` · `not-html` · `crawl-delay` · `invalid-input` (all free).

### Pricing

- **$2.50 per 1,000 companies found** ($0.0025 per company with a register number, a VAT ID, or a legal name with its
  address from the legal notice).
- **$0.002 per run** (start).
- **Misses are free**: no Impressum, no identifiers, refused, unreachable, parked, invalid input.

Example: 1,000 domains of which 700 have an Impressum with company data → 700 × $0.0025 + $0.002 = **$1.75**.

### Tips

- The Actor reads the Impressum that **German, Austrian, Swiss and Liechtenstein** websites publish. Domains from other
  countries rarely have one; a list made mostly of them stops early (misses are free, and the run tells you why).
- Paste the Impressum URL itself (`firma.de/impressum`) when you already know it — that saves a request.
- Use `confidence` / `confidenceScore` to filter: `high` means a legal name, a register number with its court and/or a
  checksum-valid VAT ID were found together.
- Use the register number to look the company up in the official Handelsregister / Firmenbuch / Zefix when you need
  certified data.
- The `vatIdChecksumValid` flag checks the official check digit. To confirm a VAT ID is currently active, check it in
  the EU VIES service.
- Some large corporate websites refuse automated visits. Those domains come back as `blocked` and are free; the Actor
  never tries to get around a refusal.

### FAQ

**Is it legal to scrape Impressum pages?**
The Impressum is a legally required, public disclosure: German (§ 5 DDG), Austrian (§ 5 ECG, § 25 MedienG) and Swiss
law require businesses to publish exactly this information so anyone can identify and contact them. The Actor reads
only these public pages, without logging in, respects each website's robots.txt (including its Crawl-delay), and visits
each website only a few times. As with any data, how you use it (for example for marketing e-mails) must follow the
GDPR, UWG and similar rules in your country. If in doubt, ask a lawyer.

**Does it access any private data?**
No. It reads public pages only — no login, no cookies, no forms. It does not collect personal names: managing
directors, board members, contact persons and data-protection officers named on an Impressum are never saved. Only the
company's own **role mailboxes** (info@, kontakt@, office@ …) are kept; personal addresses such as firstname.lastname@
are skipped. For one-person businesses without a legal form, the owner's name, street, phone and e-mail are left out.

**What does "found" mean, and when am I charged?**
A domain counts as found — and is charged — when its legal notice (or homepage footer) gives a commercial register
number, a VAT ID, or the legal company name together with its address. Everything else is free.

**Why is a domain `blocked`?**
The website refused the visit (HTTP 403, a bot check, or "too many requests"). The Actor respects that, doesn't
retry, and doesn't charge.

**Why `crawl-delay` or `disallowed`?**
The website's robots.txt either forbids the pages needed or asks for more than 10 seconds between visits. Those
websites are skipped for free.

**How fast is it?**
Roughly 1–2 domains per second with the default 10 websites at a time. Websites that ask for a pause between visits
(robots.txt Crawl-delay) take longer.

**Can I get the managing directors?**
No — this Actor deliberately leaves out people's names.

# Actor input Schema

## `domains` (type: `array`):

Company domains, website URLs or company e-mail addresses, one per line, e.g. "sipgate.de", "https://www.hetzner.com", "info@firma.at". A URL that points straight at the Impressum page is read directly. Personal mail providers (gmail.com, gmx.de, web.de …) are skipped.

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

Stop after this many companies were found (only found companies count and are charged). 0 = check the whole list.

## `countryHint` (type: `string`):

Optional: the country most of your websites are in. Used only to tell Austrian and Swiss 4-digit postcodes apart when a page doesn't say which country it is in. Leave empty to detect it from each page.

## `includeRoleEmails` (type: `boolean`):

Add the company's own role mailboxes from the Impressum (info@, kontakt@, office@, support@ …). Personal addresses (firstname.lastname@) are never collected.

## `includeMisses` (type: `boolean`):

Also save a free status row for domains where no company data was found (no Impressum, website refused, unreachable, parked …), so you can match the results back to your list. These rows carry no company data and are never charged.

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

How many different websites are checked side by side (5–20). Up to 10 per 256 MB of run memory, so 20 needs 512 MB. Each website itself gets one request at a time and its robots.txt Crawl-delay is respected.

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

Apify Proxy (datacenter) is the default and comes with every Apify plan. You can also paste your own proxy URLs.

## Actor input object example

```json
{
  "domains": [
    "sipgate.de",
    "hetzner.com",
    "world4you.com"
  ],
  "maxItems": 0,
  "countryHint": "",
  "includeRoleEmails": true,
  "includeMisses": true,
  "maxConcurrency": 10,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

All checked domains with their company data.

## `run` (type: `string`):

Status and statistics for this run.

## `report` (type: `string`):

RUN_REPORT: how the run ended, counts per status, requests and proxy use.

# 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 = {
    "domains": [
        "sipgate.de",
        "hetzner.com",
        "world4you.com"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("yugenox/impressum-company-data-extractor").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 = {
    "domains": [
        "sipgate.de",
        "hetzner.com",
        "world4you.com",
    ],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("yugenox/impressum-company-data-extractor").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 '{
  "domains": [
    "sipgate.de",
    "hetzner.com",
    "world4you.com"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call yugenox/impressum-company-data-extractor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,yugenox/impressum-company-data-extractor"
        }
    }
}
```

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/lYXM4A6EtK6sgFd4i/builds/TgBcMnlkPG5MUwpqz/openapi.json
