# Europages Scraper - European B2B Companies & Emails (`amitaviv/europages-company-scraper`) Actor

Scrape Europages B2B companies by keyword, country and company type: name, address, phone, website, employees, year founded, products; company emails from their own websites, certificates and VAT id on request. Splits searches past the 3,000 limit. New-companies monitoring. $3 per 1,000 on Bronze.

- **URL**: https://apify.com/amitaviv/europages-company-scraper.md
- **Developed by:** [Amit Aviv](https://apify.com/amitaviv) (community)
- **Categories:** Lead generation
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.40 / 1,000 companies

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

## Europages Company Scraper

Returns European B2B companies from the Europages directory (europages.co.uk, .fr, .de, .it, .es, .nl) for any keyword, optionally by country: name, full address, switchboard phone, website, company type, employees, year founded and products. On request it adds the company's email address from its own website, and certificates, VAT id and trade terms from its Europages page. Plain HTTP with no browser. Apart from the start fee you pay only for delivered companies, and a run that delivers nothing because of an error ends as Failed, never as a green empty run.

### What you get

- Company name, Europages page URL, website and website domain, switchboard phone number as published
- Street, postcode, city, country code, latitude and longitude
- Company type (manufacturer, custom manufacturer, distributor, wholesaler, service provider, retailer), employees band (e.g. `50-99`), year founded, distribution area (regional, national, Europe, international)
- Description, up to 20 product names, number of products, number of certificates, whether the company is a paying Europages customer, logo URL
- With **Find email addresses on company websites** on: the company's email address(es), read from its own website, which Europages itself does not publish (see "Email addresses")
- With **Add details** on, from each company's own Europages page: certificates (e.g. `ISO 9001`), VAT id, fax, main activity, product categories, keywords, payment methods, incoterms, catalogue PDF link, and the number of named contact persons
- Searches above the site's 3,000-company limit are read country by country and region by region (see "Large searches")
- New-companies monitoring for scheduled runs (see "Monitoring")
- One record per company, as JSON, CSV or Excel, or through the API
- A run summary (`OUTPUT_SUMMARY` in the run's key-value store): what was requested, delivered and charged; in monitoring runs how many known companies were skipped (`knownBefore`, and per search `alreadySeen`); per search how many companies Europages reports, how many were reached and which parts stayed above the limit; which inputs failed or were ignored; why the run stopped

What it does not return by default: personal data. Named contact persons and email addresses that look like a person's are only counted, unless you switch on the personal-data option (see "Legal and responsible use"). It never returns reviews or anything behind a login.

### How to use

1. Type the keywords you would type into Europages' search (for example `packaging`, `cnc machining`, `olive oil`) into **Keywords or Europages URLs**, or paste a Europages result-list, search or company URL.
2. Optionally add **Countries** (`DE`, `FR`, ...) and **Company types**.
3. Set **Maximum companies per search**, switch on **Find email addresses** if you need them, and press Start.
4. Download the results from the Output tab, or read them from the API.

### Input

| Field | Type | Default | What it does |
|---|---|---|---|
| `keywords` | list of text | none (a run without keywords fails at once with a message) | Keywords, or Europages URLs: a result list (`/companies/packaging.html`, also with a country or region in it, and with the site's filters `supplierTypes`, `employeeCounts`, `audits`, `countries`, which are kept), a search page (`/en/search?q=...`) or a company page (returns that company with its details; see "Pricing"). URLs without `https://` are accepted; duplicates and URLs of other sites are ignored and listed in the summary; other URL parameters (tracking and the like) are left out with a warning. |
| `countries` | list of text | all | Two-letter country codes (ISO; `UK` is read as `GB`). Each keyword is searched once per country, each with its own maximum. A code that is not a country (`XX`, `EN`) fails the run before any request. |
| `companyTypes` | list | all | Deliver only these types: `manufacturer`, `customManufacturer`, `distributor`, `wholesaler`, `serviceProvider`, `retailer`. Europages filters the search itself by type (all except `retailer`, which it has no filter for), so a narrow type is found across the whole search. Every delivered company is checked against the types; others are skipped and not charged. |
| `site` | choice | `en` | Which Europages language site keywords are searched on (`en`, `fr`, `de`, `it`, `es`, `nl`). Type keywords in that language. Another value fails the run before any request. |
| `maxItemsPerSearch` | number | 100 | Stop after this many companies for each keyword (and country). |
| `splitLargeSearches` | yes/no | yes | Past 3,000 companies (and only when the maximum is above 3,000), read the search by country and region. |
| `includeDetails` | yes/no | no | Read each delivered company's Europages page for certificates, VAT id and trade data. One more request per company, so much slower (see "Limits"); charged as a separate event. |
| `includeWebsiteEmails` | yes/no | no | Read each delivered company's own website for its email address. Charged as a separate event, only for companies where an address was found. |
| `includePrivateSellerData` | yes/no | no | Also return personal data: named contact persons (name, role, direct phone; needs details) and email addresses that look like a person's (needs website emails). See "Legal and responsible use". |
| `onlyNew` | yes/no | no | Monitoring: deliver and charge only companies earlier runs have not delivered for the same search. Each result page of already-known companies costs a small monitoring event (see "Pricing"). |
| `monitorKey` | text | empty | Name of the monitor memory, to keep two schedules apart. |
| `proxyConfiguration` | proxy | off | Not needed for normal runs. Turning on Apify Proxy (datacenter) makes large runs faster (see "Limits"). Company websites are always read directly. |

```json
{
  "keywords": ["packaging"],
  "countries": ["IT"],
  "maxItemsPerSearch": 300,
  "includeWebsiteEmails": true
}
```

This input ran as `duX7Hc04LPwPTunHO` on 2026-10-14: 300 Italian packaging companies in 6 minutes, 209 of them with an email address.

### Example result

From run `JM6JnKQNfeVdHEZBU` (2026-10-14, a company URL with **Add details** and **Find email addresses** on). The description, product, category and keyword lists are shortened here; nothing else is edited.

```json
{
  "id": "304108",
  "name": "PEKU Folien GmbH",
  "url": "https://www.europages.co.uk/en/company/peku-folien-gmbh-304108",
  "website": "http://www.peku.com/",
  "websiteDomain": "peku.com",
  "phone": "+49918129600",
  "street": "PEKU-Strasse 1",
  "postalCode": "92318",
  "city": "Neumarkt",
  "countryCode": "DE",
  "latitude": 49.276052,
  "longitude": 11.424341,
  "companyTypes": ["manufacturer"],
  "employees": "100-199",
  "foundingYear": 1962,
  "distributionArea": "europe",
  "description": "Own production! Film extrusion, printing in Europe's leading full HD quality up to 10 colours, confection of various bag designs - unique advice, support and kn …",
  "products": ["Soil/Fertilizer Films", "sustainable films and bags, recycling films, recycling bags", "Side Seam Bags", "Half-tube film"],
  "productCount": 17,
  "certificatesCount": 8,
  "europagesCustomer": false,
  "logoUrl": "https://wlw-1-company-facts-media20191122174836234900000006.s3.eu-central-1.amazonaws.com/b9655f37-4991-46c8-90d8-e1fe81f9cea0.png",
  "detailsFetched": true,
  "certificates": ["DIN EN ISO 50001", "DIN EN ISO 9001", "BRC", "DIN EN ISO 9001:2015", "HACCP", "DIN EN ISO 50001:2011", "ISO 50001", "ISO 9001"],
  "vatId": null,
  "fax": null,
  "mainActivity": "Packaging material",
  "productCategories": ["Bags & Pouches (Other)", "Block Bottom Bags", "Foils", "Loading Aids (Other)", "Pharmaceutical Packaging", "Promotional Bags"],
  "keywords": [],
  "paymentMethods": [],
  "incoterms": [],
  "catalogUrl": "https://wlw-1-company-facts-media20191122174836234900000006.s3.eu-central-1.amazonaws.com/135b362a-7f71-45f5-af81-c402953fdb6d.pdf",
  "contactPersons": null,
  "contactPersonsCount": 3,
  "websiteEmailsFetched": true,
  "emails": ["peku@peku.com"],
  "personalEmails": null,
  "personalEmailsCount": 0,
  "emailPages": ["http://www.peku.com/"],
  "privateDataRedacted": true,
  "searchKeyword": null,
  "searchCountry": null,
  "site": "europages.co.uk",
  "scrapedAt": "2026-10-14T15:24:30.811Z"
}
```

| Field | Meaning |
|---|---|
| `id` | Europages' company id; the same on every language site and between runs. |
| `phone` | The company's main number as published on Europages. |
| `companyTypes` | Europages' supplier types; a company can have several. |
| `employees` | Band as published (`1-4` ... `1000+`). |
| `europagesCustomer` | `true` when the company pays Europages for its listing, as the site's data says. |
| `certificatesCount`, `productCount` | Counts from the result list; the certificate names come with details. |
| `detailsFetched` | `true` when the company's Europages page was read (details on and the page answered). |
| `contactPersonsCount` | How many named contact persons the company lists on Europages (details only). |
| `websiteEmailsFetched` | `true` when the company's website answered (website emails on). |
| `emails` | Company addresses found on the website: role mailboxes (`info@`, `sales@`, `kontakt@`, ...) and mailboxes named after the company, on its own or a related domain. At most 5. |
| `personalEmailsCount`, `personalEmails` | Addresses on the website that look like a person's (a first name `luca@`, an initial `j.smith@`, a first name with a surname `lorenzolapis@`): counted, and listed only with the personal-data option. |
| `emailPages` | The website pages the addresses were found on. |
| `privateDataRedacted` | `true` when personal data (contact persons or personal addresses) exist but were left out. |
| `searchKeyword`, `searchCountry` | The search that found the company (`null` for a company URL). |

Fields the site does not provide for a company are `null` (or an empty list), never missing. When an option is off, its fields are `null` and its `...Fetched` flag is `false`.

### Pricing

Pay per event.

| Event | Free | Bronze | Silver | Gold and above |
|---|---|---|---|---|
| Actor start (once per run at the default 256 MB) | $0.0036 | $0.003 | $0.0027 | $0.0024 |
| Company delivered | $0.0036 | $0.003 | $0.0027 | $0.0024 |
| Company email (only with **Find email addresses**, only when at least one address was found) | $0.0024 | $0.002 | $0.0018 | $0.0016 |
| Company details (only with **Add details**, only when the company's page was read) | $0.0024 | $0.002 | $0.0018 | $0.0016 |
| Monitoring page re-checked (only with **Only new companies**: a result page of up to 30 companies that holds companies an earlier run delivered) | $0.00036 | $0.0003 | $0.00027 | $0.00024 |

Worked example on Bronze: 1,000 companies = $0.003 + 1,000 × $0.003 = **$3.003**. With email addresses found for 700 of them (the rate in run `duX7Hc04LPwPTunHO` was 209 of 300): $0.003 + 1,000 × $0.003 + 700 × $0.002 = **$4.403**. With details for all 1,000 as well: add 1,000 × $0.002 = **$6.403**. A monitoring run over a search of 394 companies (14 result pages) that finds nothing new costs $0.003 + 14 × $0.0003 = $0.0072; one that finds 4 new companies on those pages costs $0.0072 + 4 × $0.003 = $0.0192. A first monitoring run costs the same as a normal run.

- A company found by two of your searches in one run is delivered and charged once.
- Companies skipped by the company-type filter are not charged. A website without an address costs nothing extra.
- A pasted company URL always comes with its details at no extra charge; the details event is charged for it only when **Add details** is on.
- The maximum total charge you set for a run is respected: the actor stops before it would go over, keeps what was delivered, and says so. Run `8TsDfNoYwIf7OpBhs`: a limit of $0.03 with email addresses on delivered 5 companies with 5 addresses ($0.003 + 5 × $0.003 + 5 × $0.002 = $0.028) and ended Succeeded. A limit below the price of one company with the extras you chose ends the run as Failed before any request. With **Find email addresses** or **Add details** on, the check reserves the extra price for every company, also those that end up without an address, so a run can stop a few companies short of what its limit would pay for (run `ZIaXmGZSOoXdaGuQ0`: a $0.04 limit stopped after 7 companies with 3 addresses, $0.030 on Bronze); it never charges more than the limit.

### Email addresses

Europages shows no email addresses; it offers a contact form instead. With **Find email addresses on company websites** on, the actor reads each delivered company's website: its home page, and when that shows no company address, up to two contact or imprint pages it links to (about 30 seconds at most per company). It finds addresses in links and text, also when they are written with HTML entities or hidden by Cloudflare's email protection.

- Delivered in `emails`: role mailboxes (`info@`, `sales@`, `vertrieb@`, `biuro@`, `commerciale@`, ... in many European languages) and mailboxes named after the company (`peku@peku.com`), on the website's domain or a related one (`info@acme-group.de` for `acme.de`).
- Left out: other companies' addresses (web agency credits, a page listing distributors or agents), example addresses from forms (`jean.dupont@gmail.com`), tracking ids.
- Only counted, unless you switch on the personal-data option: addresses that look like a person's. That is any mailbox with a common first name (`anna.muster@`, `luca@lucabianchi.it`, `lorenzolapis@gmail.com`), an initial (`j.smith@`, `m.rossi@rossi.it`), or a role word plus a name (`marketing.anna@`). The company's name does not make such an address a company one, because family firms carry the family name.
- Website pages that are not web pages (a PDF or a video the company links as its website) or are larger than 3 MB are not read.

Measured on 2026-10-14 (share of delivered companies with at least one company address): Italian packaging 209 of 300 (`duX7Hc04LPwPTunHO`, before the stricter person rules, which turned about 2 to 3% of the addresses delivered in earlier test runs into counted personal ones), French industrial valves 53 of 90 (`97pr9tPuj0iSa1Di6`; most of the rest publish only a contact form), Polish injection moulding 38 of 67 (`zTvcefRc6CsH0dk2Q`), Italian olive oil 16 of 30 (`dBMiCaFeg0fOjy32i`). The rate depends on the country and the trade.

### Reliability and failure behaviour

| What happened | Run status | Status message |
|---|---|---|
| Companies delivered | Succeeded | `Scraped 60 companies from 1 query` |
| Europages has no companies for the keyword | Succeeded | `0 results: Europages has no companies for this query — "xqzzvbnmw" matches nothing; the unrelated companies Europages suggests instead were not delivered` |
| Some searches worked, some failed | Succeeded | `Scraped 120 companies from 2 queries — 1 of 2 queries failed ("…": …)` |
| Nothing delivered because of errors or blocking (tested in simulation; not produced live) | **Failed** | `No companies delivered: Europages blocked every attempt; try again later. No companies were charged (the start fee applies).` |
| Input the actor cannot use | **Failed**, within about a second | `Nothing to do: none of the 1 entries in the input is usable (first: "https://www.kompass.com/…": not a europages.co.uk / … URL). …` |
| Maximum charge reached | Succeeded | `Scraped 5 companies from 1 query — stopped at the maximum charge set for this run` |
| Run timeout close | Succeeded | `… — stopped just before the run timeout; raise the timeout to get the rest` (with email addresses on, the page being read is delivered with the websites read so far; the rest get `websiteEmailsFetched: false` and no email charge) |

- For a keyword it does not know, Europages still shows up to a page of unrelated companies. When none of the companies on such a small first page matches the keyword at all, the actor delivers nothing and says so, instead of charging you for them.
- A company website that is down or refuses the request is not an error: the company is delivered with `websiteEmailsFetched: false` and no email charge.
- Results are saved page by page. A run that is aborted, times out or is resurrected keeps what was delivered and never delivers or charges the same company twice.
- Europages refuses an address that sends too many requests in a short time (see "Limits"). The actor paces itself to stay below that, waits out a refusal (up to about 10 minutes) and then continues; a search that is still refused fails by name in the status message while the others are kept.

### Large searches (past 3,000 companies)

Europages shows at most 100 pages of 30 companies for one search. With **Split large searches** on (the default) and a maximum above 3,000, a larger search is read country by country, largest first; a country above 3,000 is read region by region and then through its own 3,000 for companies without a region. Each company is delivered and charged once. When some part still holds more than the site shows, the status message says how many of the companies Europages reports were reached. With **Company types** set, the countries are read through Europages' type filter; a country with more than 3,000 companies of those types is then also read region by region without the filter, keeping only the types asked for. Run `LYT2xp8BiYpUIkkjH`: `packaging machines`, Germany, manufacturers only, maximum 900: Europages reports 4,616 such companies; 900 delivered in 110 seconds from 30 pages, all of them manufacturers.

Run `UYMEIfmLChvMSYmWf` (2026-10-14): `packaging machines`, all countries, maximum 4,000. Europages reports 15,667 companies for it and shows 3,000. The actor read it by country, Germany (6,686) by region, and delivered 4,000 different companies in 8 minutes 19 seconds without a single refusal.

### Limits

- Speed: Europages answered an Apify address with "Human Verification" (HTTP 405) after quick bursts in our tests (roughly 100 requests within 5 minutes). The actor therefore sends at most one request every 3.5 seconds to Europages. Measured: about 480 companies a minute from result lists (4,000 in 499 s), about 50 a minute with email addresses (300 in 368 s; slow websites set the pace), about 17 a minute with **Add details** (one Europages request per company). With Apify Proxy on, Europages requests go out once a second and move to another address when refused, which is faster but not measured at scale.
- For more than about 1,000 companies with details, raise the run timeout above its default of one hour.
- The order of results is Europages' relevance order and can differ slightly between page requests (29 repeats in the 136 pages of run `UYMEIfmLChvMSYmWf`). Repeats are delivered and charged once; the run summary counts them.
- The language sites share one directory: a company has the same `id` on all of them, so the same keyword on two language sites returns mostly the same companies (each delivered and charged once per run).
- Countries: whatever Europages lists (about 45, mostly European). Descriptions come as the company wrote them; category names follow the language site.
- The keyword match is Europages' own: it includes companies related by meaning, not only by text.
- Email addresses are whatever the company's website shows today; an address is not checked for delivery. A company whose website publishes only a contact form has none.

### Monitoring: only new companies

1. Turn on **Only new companies**, set the maximum to cover the whole search, and save the input as a task.
2. Schedule the task (weekly is usually enough for a directory).
3. The first run delivers what it finds. Every later run delivers and charges only companies it has not delivered before for the same search; a run with nothing new ends as Succeeded with `0 new companies…`.

Europages sorts results by relevance, not by date, so a new company can appear anywhere in the list and every monitoring run reads the whole search again. Each result page that holds companies delivered before is charged as one "monitoring page" event ($0.0003 on Bronze, about $0.01 per 1,000 companies checked). Monitor focused searches (a keyword and a country) rather than very broad ones.

Tested on 2026-10-14: run `UrO1EbU011KhXSI58` delivered 67 Polish injection-moulding companies; the same input a minute later (`zViCT91k4ynBSAffQ`) delivered 0, ended Succeeded with `0 new companies in 2 monitored queries (no companies charged; 3 result pages re-checked at the monitoring price, and the start fee applies)` and charged the start fee plus 3 monitoring pages. The run summary counts the known companies a monitoring run skipped: `knownBefore` (distinct companies) and, per search, `alreadySeen`.

The memory is a key-value store named `europages-company-scraper-monitor` in your own account (one record per search and monitor name, up to 100,000 ids each). A company delivered for one search is remembered for every search of the run that met it. Delete the store or change **Monitor name** to start over.

### FAQ

**Do I need a proxy?** Usually not. With the actor's pacing, runs of up to 5,853 companies worked without one (one refusal, waited out). If a run of yours is refused, switch on Apify Proxy (datacenter).

**Why fewer companies than Europages says?** The site serves 3,000 per search; turn on splitting and raise the maximum. The summary shows what was reached.

**Why does a company have no email?** Its website shows none (many industrial companies offer only a contact form), the website did not answer, or the only addresses on it look like a person's (see `personalEmailsCount`).

**Can I run it from code?** Yes: the API, the Apify clients for JavaScript and Python, Make, Zapier, n8n.

**What happens when Europages changes its pages?** The actor reads the data the site embeds in its pages. If that disappears, runs fail with "a Europages page without company data" instead of returning empty results; report the run id under Issues.

### Legal and responsible use

This actor collects business directory data that Europages shows publicly without a login (company names, addresses, switchboard numbers, websites and company facts) and, on request, the company email addresses that companies publish on their own websites. By default it does not return personal data of individuals: named contact persons and person-like email addresses are only counted. The **Include personal data** option adds them; by switching it on you confirm that you have a lawful basis under the GDPR to process them, and you take responsibility for informing those people and for the direct-marketing rules of their country. Several EU countries require prior consent for cold email or calls, also between businesses, and that applies to role addresses such as `info@` as well. Some sole traders trade under their own name: that name is the company name as published. Their mailbox is treated as personal when it has a first name or an initial in it; a mailbox that is only the company's domain name or surname (`weber@hans-weber.de`) is delivered as a company address.

Europages' terms of use forbid downloading its addresses to build a database and using its data to solicit its users; its operator, Visable, claims database rights in the directory. Use the output for research, sourcing and analysis, keep extracts proportionate, and do not re-publish the directory. You are responsible for respecting the site's terms, database rights and data-protection law in your country; if you are unsure, ask a lawyer before you build on the data.

### Related actors

- [Company Hiring Tracker](https://apify.com/amitaviv/company-hiring-tracker): paste the `websiteDomain` values from this actor's output and see which of these companies are hiring, in which functions and countries, and what changed since your last run.
- [Welcome to the Jungle Scraper](https://apify.com/amitaviv/welcome-to-the-jungle-scraper): headcount, tech tools and open jobs per company for firms that recruit on Welcome to the Jungle (mostly France), to qualify a company list.
- [Yandex Maps Scraper](https://apify.com/amitaviv/yandex-maps-scraper): local businesses with address, phones, website and opening hours from Yandex Maps (Russia, the CIS countries, Türkiye), when you need local suppliers and service firms that are not in a B2B directory.

### Changelog

- 2026-10-14 0.1: first version, with email addresses from company websites. Later the same day: the company-type filter runs on Europages itself; pasted result-list URLs keep their filters; country codes and the site are checked before the run; stricter rules for addresses that name a person; a run stopped by its timeout delivers the page it was reading; the monitoring-page event; the run summary counts the known companies a monitoring run skipped (`knownBefore`).

### Support

Open an issue on the actor's **Issues** tab with the run id.

# Actor input Schema

## `keywords` (type: `array`):

What you would type into Europages' search, one per line (e.g. "packaging", "cnc machining", "olive oil"). You can also paste Europages URLs: a result list (https://www.europages.co.uk/companies/packaging.html, also with a country, region or page in it, and with the site's own filters such as ?supplierTypes=Production, which are kept), a search page (…/en/search?q=packaging) or a company page (one record with its full details, charged as a details event only when "Add details" is on). Sites read: europages.co.uk, .fr, .de, .it, .es, .nl. Each delivered company is one "company" charge. A run without any keyword or URL fails at once with a message.

## `countries` (type: `array`):

Two-letter country codes (ISO), e.g. DE, FR, IT, ES, PL, GB (UK is read as GB). Each keyword is searched once per country (each is its own search, with its own maximum). A code that is not a country, such as XX or EN, stops the run before any request. Leave empty for all countries.

## `companyTypes` (type: `array`):

Deliver only companies of these types, as Europages lists them; a company can have several. Europages filters the search itself by type (all types except retailer, which it has no filter for), so a narrow type is found across the whole search, not only among its first 3,000 companies. Example: \["manufacturer", "wholesaler"]. Leave empty for all.

## `site` (type: `string`):

Which Europages site keywords are searched on. Type keywords in its language ("packaging" on the English site, "emballage" on the French one). The company data is the same; descriptions and category names come in that site's language where the company provided them. Default: en. Any other value stops the run before any request.

## `maxItemsPerSearch` (type: `integer`):

Number of companies: the most delivered (and charged) for each keyword and country (default 100, up to 200,000). Europages itself shows at most 3,000 companies per search; above that see "Split large searches".

## `splitLargeSearches` (type: `boolean`):

When a search has more than 3,000 companies and your maximum is above 3,000, read it country by country, and countries above 3,000 region by region, so you get far more than the site shows in one list. Each company is delivered and charged once. Run summary (OUTPUT_SUMMARY) says how many of the companies Europages reports were reached. Default on.

## `includeDetails` (type: `boolean`):

Also read each delivered company's Europages page for: certificates (ISO 9001 etc.), VAT id, fax, main activity, product categories, keywords, payment methods, incoterms, catalogue link. One more request per company, so runs are slower; charged as an extra "company details" event only for companies whose page was read. Default off: those fields are null and detailsFetched is false.

## `includeWebsiteEmails` (type: `boolean`):

Europages publishes no email addresses. Switch this on to read each delivered company's own website (home page, and up to two contact or imprint pages it links to) for its email address. Returns role addresses such as info@, sales@ or kontakt@ and mailboxes named after the company, on its own domain. Addresses that look like a person's (a first name, an initial such as j.smith@, or a first name with a surname) are only counted unless you also switch on the personal-data option below. Charged as an extra "company email" event only for companies where an address was found. Adds about half a minute per page of 30 companies. Default off: emails is null and websiteEmailsFetched is false.

## `includePrivateSellerData` (type: `boolean`):

Off by default: records give only the number of named contact persons a company lists on Europages and the number of personal-looking email addresses on its website. Switch on to add the persons' names, roles and direct phone numbers (needs "Add details") and those email addresses (needs "Find email addresses"). These are personal data under the GDPR: by switching this on you confirm that you have a lawful basis to process them and will respect the rules on direct marketing that apply to you.

## `onlyNew` (type: `boolean`):

Deliver and charge only companies that earlier runs of this actor in your account have not delivered for the same search. Europages sorts by relevance, not by date, so each run reads the whole search up to its maximum (set the maximum to cover the whole search); each result page that holds companies delivered before is charged as a small "monitoring page" event ($0.0003 on Bronze, about $0.01 per 1,000 companies checked). Useful on a schedule to catch companies newly listed for a keyword. The memory is a key-value store named europages-company-scraper-monitor in your account; delete it to start over. Default off.

## `monitorKey` (type: `string`):

Only with "Only new companies". Any short name, e.g. packaging-it-weekly. Runs with the same search and the same monitor name share one memory. Give two schedules different names to keep their memories apart. Default: empty (one memory per search).

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

Off by default, and that is the recommended setting: with the actor's pacing, Europages answered our test runs from Apify's own addresses (one refusal in 5,853 companies, waited out). If a run reports that it was blocked, switch on Apify Proxy (datacenter is enough); each retry then goes out from a different address. Company websites are always read directly.

## Actor input object example

```json
{
  "keywords": [
    "packaging"
  ],
  "countries": [],
  "site": "en",
  "maxItemsPerSearch": 100,
  "splitLargeSearches": true,
  "includeDetails": false,
  "includeWebsiteEmails": false,
  "includePrivateSellerData": false,
  "onlyNew": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

All delivered companies as JSON, one object per company: id, name, url (Europages page), website, websiteDomain, phone, street, postalCode, city, countryCode, latitude, longitude, companyTypes, employees (band), foundingYear, distributionArea, description, products, productCount, certificatesCount; with Add details also certificates, vatId, fax, mainActivity, productCategories, paymentMethods, incoterms, catalogUrl; with Find email addresses also emails. Fields not requested are null.

## `resultsCsv` (type: `string`):

All delivered records as a CSV file.

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

What was requested, delivered and charged; in monitoring runs how many known companies were skipped (knownBefore); per search what Europages reports against what was reached, how it was split, and which parts stayed above the site's limit; failed or ignored inputs; warnings; why the run stopped.

# 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 = {
    "keywords": [
        "packaging"
    ],
    "countries": [],
    "maxItemsPerSearch": 100,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("amitaviv/europages-company-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 = {
    "keywords": ["packaging"],
    "countries": [],
    "maxItemsPerSearch": 100,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("amitaviv/europages-company-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 '{
  "keywords": [
    "packaging"
  ],
  "countries": [],
  "maxItemsPerSearch": 100,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call amitaviv/europages-company-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,amitaviv/europages-company-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/viHh6swFqi4NHu28j/builds/SkhCs1VuZHIJ3qzXK/openapi.json
