# German Imprint Scraper - Impressum Company Data & Contacts (`kamerozkan/german-imprint-scraper`) Actor

Turn a list of company websites into structured Impressum data: legal company name, legal form, address, phone, email, managing directors, Handelsregister court and number (HRB/HRA) and VAT ID. For B2B lead lists and KYB checks in Germany, Austria and Switzerland.

- **URL**: https://apify.com/kamerozkan/german-imprint-scraper.md
- **Developed by:** [Kamer Ozkan](https://apify.com/kamerozkan) (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 $2.80 / 1,000 impressum parseds

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

## German Imprint Scraper - Impressum Company Data & Contacts

Turn a list of German, Austrian or Swiss company websites into clean **Impressum data**: legal company name, legal form, street, ZIP, city, phone, fax, email, managing directors, **Handelsregister court and number (HRB / HRA / PR / VR, Austrian FN, Swiss UID)** and **VAT ID (USt-IdNr.)**. One row per website, charged only when an Impressum was found and read.

### What does German Imprint Scraper do?

Every business website in Germany (section 5 DDG, formerly TMG), Austria (ECG / UGB) and Switzerland (UWG) must publish an Impressum or legal notice. This Actor opens each website you give it, follows the **Impressum / Imprint / Legal notice** link (or tries `/impressum` and `/imprint`), and parses that page into structured company fields. It needs no login, no API key and no proxy setup, and it respects each site's robots.txt.

Insurers, professional chambers, regulators, ombudsman offices and web agencies that appear in many Impressum pages (for example "Berufshaftpflichtversicherung: ... Versicherung AG") are recognised and are not returned as the company.

### Who is it for?

- **B2B sales and lead generation**: enrich a Google Maps or directory export with the legal entity name, managing directors and a verified business address before outreach.
- **KYB, compliance and onboarding teams**: collect the Handelsregister number, register court and VAT ID of suppliers or merchants in one run, then check them in the official registers.
- **Data and CRM teams**: deduplicate accounts by legal entity, fill missing legal names and HRB numbers, and keep company records current.

### What data can you get?

| Field | Example |
|---|---|
| `companyName` | Alfred Ritter GmbH & Co. KG |
| `legalForm` | GmbH & Co. KG |
| `street`, `postalCode`, `city`, `country` | Alfred-Ritter-Strasse 25, 71111, Waldenbuch, DE |
| `phone`, `fax` | 49 (0) 71 57 / 97-0 |
| `email` | info@ritter-sport.de |
| `managingDirectors` | \["Tim Hoppe", "Moritz Ritter", ...] |
| `registerCourt` | Stuttgart |
| `registerType`, `registerNumber` | HRA, HRA 242329 |
| `vatId` | DE147645259 |
| `impressumUrl` | https://www.ritter-sport.com/de/impressum |
| `website`, `domain`, `input`, `scrapedAt` | where the data came from and when |

Fields that a site does not publish are `null` (or an empty list for `managingDirectors`).

### How much does it cost?

You pay only for websites whose Impressum was read: **$3.50 per 1,000 Impressum records** on the Free plan, with lower prices on paid Apify plans (Bronze $3.15, Silver $2.975, Gold and above $2.80 per 1,000). Websites that cannot be opened, show a bot check, block the page in robots.txt, render the Impressum only with JavaScript, or have no Impressum are **free** and listed in the `NOT_FOUND` record of the run's key-value store with the reason.

Example: a lead list of 1,000 websites where 850 have a readable Impressum costs 850 x $0.0035 = **$2.98** on the Free plan. Set **Max Impressum records** or a maximum cost per run to cap spending.

### How to use it

1. Click **Try for free**.
2. Paste company websites or domains into **Company websites**, one per line (`tchibo.de`, `https://www.alnatura.de`). From another Actor or an integration, pass them as **Start URLs** in the `{"url": "..."}` format, for example the `website` column of a Google Maps export.
3. Optionally set **Max Impressum records**.
4. Click **Start** and download the results as JSON, CSV, Excel or via API. The Overview table shows one company per row.

### Input example

```json
{
  "websites": ["ritter-sport.de", "bergfreunde.de", "alnatura.de", "fielmann.de", "tchibo.de"],
  "maxItems": 100
}
```

### Output example

Real rows from a test run on 2026-10-14:

```json
[
  {
    "input": "tchibo.de",
    "website": "https://www.tchibo.de/",
    "domain": "tchibo.de",
    "impressumUrl": "https://www.tchibo.de/c/service-impressum",
    "companyName": "Tchibo GmbH",
    "legalForm": "GmbH",
    "street": "Überseering 18",
    "postalCode": "22297",
    "city": "Hamburg",
    "country": "DE",
    "phone": "+49 (0) 40 63 87 - 0",
    "fax": null,
    "email": "service@tchibo.de",
    "managingDirectors": ["Erik Hofstädter", "Felix Albrecht", "Hamid Dastmalchian"],
    "registerCourt": "Hamburg",
    "registerType": "HRB",
    "registerNumber": "HRB 43618",
    "vatId": "DE811164447",
    "scrapedAt": "2026-10-14T08:21:19Z"
  },
  {
    "input": "https://guhr-steuerberatung.de/",
    "website": "https://guhr-steuerberatung.de/",
    "domain": "guhr-steuerberatung.de",
    "impressumUrl": "https://guhr-steuerberatung.de/impressum/",
    "companyName": "Guhr Steuerberatungsgesellschaft mbH",
    "legalForm": "mbH",
    "street": "Auerstraße 14",
    "postalCode": "10249",
    "city": "Berlin",
    "country": "DE",
    "phone": "030 303 665 840",
    "fax": null,
    "email": "anfrage@guhr-steuerberatung.de",
    "managingDirectors": ["Karsten Guhr"],
    "registerCourt": "Berlin-Charlottenburg",
    "registerType": "HRB",
    "registerNumber": "HRB 197449 B",
    "vatId": "DE318982011"
  }
]
```

### Integrations and API

Run it from your code with the Apify API or the `apify-client` package, schedule it in Apify, or connect it to Make, n8n, Zapier, Google Sheets or a webhook. A common flow is Google Maps scrape, then this Actor on the `website` column, then your CRM.

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("kamerozkan/german-imprint-scraper").call(run_input={"websites": ["tchibo.de", "alnatura.de"]})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["companyName"], item["registerNumber"], item["vatId"])
```

### FAQ

**Which countries work?** Germany, Austria and Switzerland, where the Impressum is mandatory. Sites in other countries work when they publish a page called Impressum, Imprint, Legal notice, Mentions légales or Note legali.

**What happens with a site whose Impressum is built with JavaScript?** The Actor uses plain HTTP and does not run a browser. If the Impressum page has no readable text, the site is skipped, not charged and listed in `NOT_FOUND` with the reason "built with JavaScript".

**Does it respect robots.txt?** Yes. If a site's robots.txt disallows its Impressum page, the page is not fetched and the site is not charged.

**Are the managing directors personal data?** They are the legal representatives the company itself must publish in its Impressum. Sole traders and freelancers publish their own name as the business; the Actor returns it only as that business contact and does not enrich it from other sources. You are responsible for using the data in line with GDPR, for example for B2B outreach with a legitimate interest.

**Why is `registerNumber` empty for some companies?** Sole traders, GbR partnerships and freelancers are not in the Handelsregister, so their Impressum has no register entry. Partnerships (PartG) show a `PR` number and associations a `VR` number.

**Can I give it full page URLs instead of domains?** Yes. Any page of the site works; the Actor finds the Impressum from there.

**Something is not working?** Open an issue on the Issues tab with your run link and the website, and we will fix it fast.

### Support

Found a website where a field is wrong or missing? Open an issue on the Actor's Issues tab with the website; we usually answer within a day.

# Actor input Schema

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

Company websites or domains, one per line, for example "tchibo.de" or "https://www.alnatura.de". The Actor opens the homepage, follows the Impressum / Imprint / Legal notice link (or tries /impressum) and reads the legal notice. Duplicate domains are removed.

## `startUrls` (type: `array`):

Same as Company websites, in the {"url": "..."} format other Actors and integrations produce, for example the website field of a Google Maps export. Both lists are combined.

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

Stop after this many Impressum records in the dataset. You are charged only per website whose Impressum was read, so this also caps the cost of the run.

## Actor input object example

```json
{
  "websites": [
    "ritter-sport.de",
    "bergfreunde.de",
    "alnatura.de",
    "fielmann.de",
    "tchibo.de"
  ],
  "maxItems": 100
}
```

# Actor output Schema

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

One row per website whose Impressum was read.

# 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": [
        "ritter-sport.de",
        "bergfreunde.de",
        "alnatura.de",
        "fielmann.de",
        "tchibo.de"
    ],
    "maxItems": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("kamerozkan/german-imprint-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 = {
    "websites": [
        "ritter-sport.de",
        "bergfreunde.de",
        "alnatura.de",
        "fielmann.de",
        "tchibo.de",
    ],
    "maxItems": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("kamerozkan/german-imprint-scraper").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": [
    "ritter-sport.de",
    "bergfreunde.de",
    "alnatura.de",
    "fielmann.de",
    "tchibo.de"
  ],
  "maxItems": 100
}' |
apify call kamerozkan/german-imprint-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,kamerozkan/german-imprint-scraper"
        }
    }
}
```

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/CndcK0gbu773elaFz/builds/ZW5oecRwQ4P9k6M49/openapi.json
