# Website Compliance Scanner - Impressum, Privacy, Cookie Consent (`santamaria-automations/compliance-scanner`) Actor

Scan any website for legal compliance markers: Impressum / imprint, privacy policy, cookie-consent banner. Returns a HIGH / MEDIUM / LOW risk flag tuned for DACH GDPR / Abmahnung exposure. Pay-per-result.

- **URL**: https://apify.com/santamaria-automations/compliance-scanner.md
- **Developed by:** [NanoScrape](https://apify.com/santamaria-automations) (community)
- **Categories:** Developer tools, Automation, Lead generation
- **Stats:** 4 total users, 3 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 url scanneds

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

## Compliance Scanner

**Impressum, privacy policy, cookie consent. One HTTP probe, one risk flag.**

Point this actor at any website URL and it returns a structured compliance snapshot: is there an Impressum, is there a privacy policy, is there a cookie-consent banner, which consent vendor is running, and a risk flag tuned for DACH GDPR / Abmahnung exposure.

Pure Go HTTP with a real Chrome 124 TLS fingerprint. No browser, no JavaScript rendering. Fast enough to scan a lead list of thousands in minutes.

### Features

- **Impressum detection.** Anchor-text scan on the homepage plus targeted probes of `/impressum`, `/legal-notice`, `/imprint`, `/mentions-legales`, `/note-legali`, `/aviso-legal`, `/juridische-informatie`.
- **Privacy policy detection.** Same shape: anchor-text scan plus path probes for `/datenschutz`, `/privacy`, `/privacy-policy`, `/politique-confidentialite`, and equivalents.
- **Cookie consent detection.** Identifies Cookiebot, Usercentrics, OneTrust, Iubenda, TrustArc, Consentmanager, Complianz, Borlabs, Klaro, Termly, and Quantcast. Falls back to a generic banner marker when the vendor cannot be identified.
- **Language detection.** Reads `<html lang>` first, falls back to a German stopword count for sites without a language attribute. Emits a two-letter code.
- **Risk flag.** HIGH when a German-language site is missing an Impressum (Abmahnung exposure). MEDIUM on softer gaps. LOW when all three markers are present. UNKNOWN when the homepage cannot be fetched.
- **Tracking detection.** Flags the presence of Google Analytics, GTM, Meta Pixel, Hotjar, LinkedIn Insight, TikTok Pixel, Matomo, and others so you can spot "tracking without consent" cases.
- **Fast.** 5 URLs in parallel by default. Runs at 256 MB RAM with no browser overhead.

### DACH use case: Abmahnung avoidance

German-language sites without a valid Impressum are directly actionable under Section 5 TMG and Section 55 RStV. Lawyers issue Abmahnung letters for a few hundred euros a pop, and the penalty stack grows fast on repeat offenders. Same story for missing privacy policies and tracking cookies set before consent.

This scanner is the fastest way to build a prioritized list of local businesses that need help. Feed it a Google Maps export or a lead scrape, filter for `risk_flag = "HIGH"`, and you have a warm outreach list for a legal-tech agency, GDPR consulting practice, or marketing shop selling Impressum-Generator plugins.

### When to use it

- **Legal-tech and GDPR consulting.** Bulk-prospect leads by compliance gap.
- **Marketing agencies.** Filter your web-design lead list for sites that visibly need work.
- **Sales enablement.** Add a compliance signal to your CRM enrichment pipeline.
- **Compliance monitoring.** Snapshot your own domain portfolio nightly and catch regressions.
- **Vendor migration research.** Discover which consent tool a competitor or partner runs.

### Input

| Parameter | Type | Default | Description |
|---|---|---|---|
| `urls` | array | **required** | Website homepage URLs to scan. Bare domains accepted. |
| `companies` | array | `[]` | Alternative paired input: `[{"company_id":"...","website_url":"..."}]` for CRM join-back. |
| `probeTimeoutMs` | integer | `5000` | HTTP timeout per fetch. Cap 15000. |
| `respectRobotsTxt` | boolean | `true` | Honor the site's robots.txt on path probes. |
| `concurrency` | integer | `5` | Number of URLs scanned in parallel. |
| `proxyConfiguration` | object | Apify datacenter | Optional proxy. Datacenter is fine for compliance probes. |

### Output shape

One row per input URL:

```json
{
  "url": "https://example.de/",
  "final_url": "https://www.example.de/",
  "status_code": 200,
  "site_language": "de",
  "has_impressum": true,
  "impressum_url": "https://www.example.de/impressum",
  "has_privacy_policy": true,
  "privacy_policy_url": "https://www.example.de/datenschutz",
  "has_cookie_consent": true,
  "consent_tool": "usercentrics",
  "sets_tracking_cookies": true,
  "risk_flag": "LOW",
  "risk_reasons": [],
  "probed_at": "2026-07-21T09:00:00Z"
}
```

When the probe fails:

```json
{
  "url": "https://broken.example/",
  "status_code": 0,
  "risk_flag": "UNKNOWN",
  "risk_reasons": ["probe_failed"],
  "probed_at": "2026-07-21T09:00:00Z",
  "error": "request timed out"
}
```

#### Risk flag semantics

| flag | Meaning |
|---|---|
| `HIGH` | Missing Impressum on a German-language site. Directly actionable under Abmahnung practice. |
| `MEDIUM` | Any other single compliance gap (missing privacy policy, tracking without consent, missing Impressum on non-DE site). |
| `LOW` | Impressum, privacy policy, and cookie consent all present. |
| `UNKNOWN` | Homepage could not be fetched. |

Risk reasons are stable machine-readable strings you can filter on:

- `missing_impressum_de_site`
- `missing_impressum`
- `missing_privacy_policy`
- `tracking_without_consent`
- `probe_failed`

### Pricing

- **$0.001** per run start
- **$0.003** per URL scanned

Failed probes are billed too. They still consumed a run slot and returned a UNKNOWN row so you can retry the URL later.

**1000 URLs = $3.00.**

### Related Actors

- [Broken Link Checker](https://apify.com/santamaria-automations/broken-link-checker). Find 404s, redirects, SSL errors, and dead outbound links.
- [SSL Certificate Inspector](https://apify.com/santamaria-automations/ssl-certificate-inspector). Inspect TLS certificates and TLS versions for any host.
- [Website Tech Stack Detector](https://apify.com/santamaria-automations/website-tech-detector). Identify the CMS, frameworks, analytics, and hosting behind any site.
- [SEO Metadata Extractor](https://apify.com/santamaria-automations/seo-metadata-extractor). Pull titles, meta tags, Open Graph, Twitter Cards, and JSON-LD schema.

### Issues & Feedback

Found a bug or a compliance signal we should detect? Please open an issue on the actor page.

# Actor input Schema

## `urls` (type: `array`):

List of website homepage URLs to probe. You can provide bare domains (example.com) or full URLs (https://www.example.com/). Each URL is scanned independently and produces one result row.

## `companies` (type: `array`):

Alternative to urls. Pass an array of {company\_id, website\_url} pairs when you want the company\_id echoed back on the output row for CRM join-back. Both urls and companies may be supplied together.

## `probeTimeoutMs` (type: `integer`):

HTTP timeout applied to every fetch (homepage + path probes). Sites with slow origin servers may need a higher value.

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

Honor the site's robots.txt when probing legal page paths. Homepage is always fetched. Disable only when auditing a site you own or operate.

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

Number of URLs probed in parallel. Compliance probes are lightweight, but the default of 5 keeps load on each target site polite.

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

Optional Apify proxy settings. Datacenter proxy is sufficient for compliance probes. Enable if your run is hitting rate limits.

## `preFetchedByURL` (type: `object`):

Map of URL -> pre-fetched homepage result. When set, this actor uses the provided HTML for its initial homepage step (CMP detection, cookie consent) instead of fetching. Path probes for /impressum, /datenschutz etc. still fetch normally. Used by the google-maps-scraper orchestrator to consolidate homepage fetches. Direct users should leave this blank.

## Actor input object example

```json
{
  "urls": [
    "https://www.deutschebank.de/"
  ],
  "companies": [],
  "probeTimeoutMs": 5000,
  "respectRobotsTxt": true,
  "concurrency": 5,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "BUYPROXIES94952"
    ]
  }
}
```

# Actor output Schema

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

Dataset with one row per URL. Fields: impressum / privacy / cookie-consent presence, consent tool name, site language, and risk flag.

# 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 = {
    "urls": [
        "https://www.deutschebank.de/"
    ],
    "companies": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("santamaria-automations/compliance-scanner").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 = {
    "urls": ["https://www.deutschebank.de/"],
    "companies": [],
}

# Run the Actor and wait for it to finish
run = client.actor("santamaria-automations/compliance-scanner").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 '{
  "urls": [
    "https://www.deutschebank.de/"
  ],
  "companies": []
}' |
apify call santamaria-automations/compliance-scanner --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=santamaria-automations/compliance-scanner",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

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