# EU Legal Entity Extractor - VAT, Registry & Imprint API (`changeable_peddler/eu-legal-entity-extractor`) Actor

Extract legal company identity, VAT IDs, registry numbers, addresses, and public contacts from EU and UK website legal pages.

- **URL**: https://apify.com/changeable_peddler/eu-legal-entity-extractor.md
- **Developed by:** [Sean J](https://apify.com/changeable_peddler) (community)
- **Categories:** Lead generation, Business, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 website processeds

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

### What does EU Legal Entity Extractor do?

**EU Legal Entity Extractor** collects company names and legal identifiers published on EU/UK websites, with source-linked contact and imprint evidence. Try one public [imprint page](https://www.bosch.de/impressum/) in [the Actor](https://apify.com/changeable_peddler/eu-legal-entity-extractor), then export the result or connect it through Apify’s API and integrations. Optional platform scheduling can repeat a check, but the Actor does not create a monitor or compare runs for you.

### Why use EU Legal Entity Extractor?

Use it when a vendor-onboarding or CRM-review queue needs website-published identity evidence before a person checks an official register. Country and confidence are inferred signals, so they should not determine a KYC/KYB decision by themselves.

### How to use EU Legal Entity Extractor

1. Supply one public legal-page URL in the Input tab.
2. Keep evidence enabled and budget for the $0.002 attempt plus possible $0.008 found-entity event.
3. Review the returned identifiers against their sources before expanding the input.

### Input

This public-site example shows the input format, not a promised result:

```json
{
  "startUrls": [{ "url": "https://www.bosch.de/impressum/" }],
  "maxPagesPerSite": 4,
  "concurrency": 1,
  "requestTimeoutSecs": 10,
  "includeEvidence": true,
  "validateVat": false
}
```

Use `startUrls` or bare `domains`, with at most 100 combined entries including duplicates. The Input tab describes the remaining options and their limits.

### Output

This shortened illustration uses a placeholder company, not a live extraction or customer result:

```json
{
  "domain": "company.example",
  "status": "PARTIAL",
  "companyName": "Example GmbH",
  "vatIds": [],
  "registryIds": [],
  "legalPageUrls": ["https://company.example/impressum"],
  "vatValidations": []
}
```

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel. Retain `retrievedAt` and source evidence with the exported values so a reviewer can revisit the publication context.

### Data table

| Field | Meaning |
|---|---|
| `companyName`, `country` | Extracted name and inferred jurisdiction, not registry-confirmed identity. |
| `vatIds`, `registryIds` | Normalized VAT strings and matched register identifiers. |
| `vatValidations` | Optional VIES results, including unavailable or unsupported states. |
| `evidence`, `sourceUrls` | Snippets and checked source URLs for manual review. |
| `status`, `errors` | Detection status and source or budget problems. |

### Pricing / Cost estimation

How much does it cost to check a website? The current fees are **$0.002 per attempted website** (`website-processed`) plus **$0.008 for a qualifying FOUND entity** (`legal-entity-found`), totalling **$0.01** when both events apply. The found-entity event requires `FOUND` status with at least one VAT or registry identifier; `PARTIAL`, `NO_LEGAL_ENTITY` and ordinary `FETCH_FAILED` rows incur no found-entity event, although the attempt fee can apply.

The run reserves both fees before starting a website, even when the eventual result needs only the attempt fee. Check the Pricing tab for current platform terms and plan limits, and inspect `RUN_SUMMARY` before repeating an uncertain run. No additional private VAT-service key is required.

For stopped runs, check `RUN_ABORT_STATE`; an incomplete checkpoint or unknown final counts take precedence over any stale `RUN_SUMMARY`. Confirmed-so-far counts are lower bounds, not final totals.

### Tips and advanced options

Start at the known imprint or legal page to make the limited check more relevant. Each site has a **20-second deadline**, a **1 MiB downloaded-response budget** and a **4 MiB decoded-text budget**; failed requests, redirects and optional VIES requests consume its attempt allowance. `maxPagesPerSite` sets that allowance, not a guarantee that every candidate page will be read.

`validateVat` defaults to true; set it false to skip VIES. When enabled, up to five detected IDs may be checked within the remaining site budget. A service outage or incomplete check is not an invalid-VAT verdict, and non-supported identifiers cannot be validated through VIES.

### FAQ, disclaimers and support

The Actor reads static public pages without a browser or OCR, so script-rendered or image-only details may be missed. It does not bypass sign-in, configure proxy rotation or verify corporate ownership, sanctions or legal compliance. A missing identifier means it was not detected in the checked pages, rather than proving that none exists.

Only inspect websites you are permitted to check and verify important identifiers independently. Use the [Issues tab](https://apify.com/changeable_peddler/eu-legal-entity-extractor/issues) with a sanitized example for support or to discuss a custom scope.

# Actor input Schema

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

Submitted public website URLs. At most 100 entries combined with domains, including duplicates. Checks are limited to public same-domain pages; credentials and nonstandard ports are not accepted.

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

Optional public bare domains, one item per company. At most 100 entries combined with startUrls, including duplicates.

## `maxPagesPerSite` (type: `integer`):

Maximum actual HTTP requests per website, including redirects and failed attempts and optional VIES checks. Work may stop earlier at the shared 20-second deadline, 1 MiB response-body download budget or 4 MiB retained-text budget.

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

Number of websites to process in parallel.

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

Upper bound in seconds for one request. The remaining overall 20-second website budget can stop it sooner.

## `includeEvidence` (type: `boolean`):

Include source URLs and short snippets explaining where each field was found.

## `validateVat` (type: `boolean`):

Best-effort validation of up to five detected EU VAT IDs with VIES, only while the shared request/time/byte budget allows. Unavailable or skipped checks are unknown, not invalid. Non-EU IDs are not validated.

## `userAgent` (type: `string`):

HTTP User-Agent used when fetching public website pages.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.bosch.de/impressum/"
    }
  ],
  "domains": [],
  "maxPagesPerSite": 8,
  "concurrency": 5,
  "requestTimeoutSecs": 20,
  "includeEvidence": true,
  "validateVat": true,
  "userAgent": "Mozilla/5.0 (compatible; EU-Legal-Entity-Extractor/1.0; +https://apify.com/)"
}
```

# Actor output Schema

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

One row per input website or domain with detected company identity, VAT IDs, registry IDs, public contacts, evidence, and risk flags.

## `runSummary` (type: `string`):

Counts for processed, found, partial, failed, and charged events.

# 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 = {
    "startUrls": [
        {
            "url": "https://www.bosch.de/impressum/"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("changeable_peddler/eu-legal-entity-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 = { "startUrls": [{ "url": "https://www.bosch.de/impressum/" }] }

# Run the Actor and wait for it to finish
run = client.actor("changeable_peddler/eu-legal-entity-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 '{
  "startUrls": [
    {
      "url": "https://www.bosch.de/impressum/"
    }
  ]
}' |
apify call changeable_peddler/eu-legal-entity-extractor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,changeable_peddler/eu-legal-entity-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/m0CbBhV6ZAkg39j5J/builds/lyFzzR0h3hQ1nGuaW/openapi.json
