# Italy Company Registry & PEC Scraper - Registro Imprese (`scrapersdelight/it-company-pec-scraper`) Actor

Italian company data from the Registro Imprese via ufficiocamerale.it: search by name, Partita IVA or REA, or paste URLs. VAT, REA, ATECO, legal form, status, address, employees, revenue, profit, share capital, PEC and SDI code. $0.001 per company + $0.10 per run.

- **URL**: https://apify.com/scrapersdelight/it-company-pec-scraper.md
- **Developed by:** [Scrapers Delight](https://apify.com/scrapersdelight) (community)
- **Categories:** Lead generation, Business, Automation
- **Stats:** 4 total users, 3 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 company records

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

## Italy Company Registry & PEC Scraper - Registro Imprese, VAT, REA

**Turn any Italian company name, VAT number (Partita IVA) or REA code into a structured registry record.** The data comes from the public company pages on [ufficiocamerale.it](https://www.ufficiocamerale.it), which republish Registro Imprese / Camera di Commercio information: VAT number, tax code, REA, chamber of commerce, legal form, status, ATECO activity, registered address, employees, revenue, profit, share capital, the **PEC** certified email and the **SDI codice destinatario** for e-invoicing - one flat row per company.

Search by name, VAT number or REA code, paste company page URLs, or send a whole batch list. Cloudflare and the Italy-only IP requirement are handled for you. Optional add-on: the company's own **verified website and contact email**.

### Why use this scraper

- **Every VAT number works.** Each Partita IVA is looked up through the site's own search, so it finds the company whatever its page address looks like. An 11-digit number is matched as the Partita IVA or the numeric codice fiscale (Enel S.p.A.: codice fiscale `00811720580`, Partita IVA `00934061003` - both find it). Mistyped numbers fail the check digit and are never fetched or charged.
- **REA lookup that returns the right company.** A REA code is resolved to candidate companies and a record is delivered only when that company's own card carries the same chamber and REA number.
- **$0.001 per company + $0.10 per run.** No charge for companies that are not found, invalid numbers or unreachable lookups.
- **Financials from the free page.** Revenue (Fatturato), profit (Utile), share capital and employees, each with the year the card prints beside it.
- **PEC confirmed twice.** The card carries the PEC in its visible block (Cloudflare-obfuscated) and in its schema.org data; both are read and compared (`pec_matches_structured_data`).
- **Only-with-PEC filter.** `onlyWithPec` skips companies without a PEC - not delivered, not charged.
- **Verified websites only.** With `enrichEmails`, a website is attached only when one of its pages shows the company's tax code / VAT number, its registered postcode and town, or its registered name with its legal form. Anything else goes to `website_candidate`, with no email taken from it and no charge.

#### Coming from another Registro Imprese scraper?

Input names (`mode`, `query`, `province`, `directUrls`, `maxItems`, `maxConcurrency`, `includePec`, `enrichEmails`) and output field names (`vat_number`, `rea_number`, `legal_name`, `pec_email`, `codice_destinatario`, ...) follow the conventions already used for ufficiocamerale.it data on the Store, so an existing input or pipeline works unchanged.

| | This actor |
|---|---|
| Price per company | **$0.001** |
| Actor start | $0.10 per run |
| VAT lookup | every Partita IVA, through the site's own search (not only VATs that appear in a page address) |
| REA lookup | resolved and checked against the company's own card |
| Revenue / profit / share capital / employees from the free page | yes, each with its year |
| SDI codice destinatario | yes (the `0000000` default is kept apart in `codice_destinatario_as_published`) |
| PEC from the page | yes, confirmed against the page's structured data |
| PEC from INI-PEC when the page has none | no - INI-PEC asks for a CAPTCHA on every search (see FAQ) |
| Only companies with a PEC | yes (`onlyWithPec`, skipped companies not charged) |
| Website + email add-on | $0.0009 per verified website, proof type in `website_matched_by` |
| Directors, shareholders, insolvency, XBRL bilancio | `null` - those are paid visure, not on the free page |
| Batch list mixing VAT numbers, names, REA codes and URLs | yes (`identifiers`) |

### Supported inputs

The actor takes a **search** (`mode` + `query`), a list of **direct company URLs**, a **batch list**, or any combination.

**Search modes**

- `by_name` - searches the company name on the site, best match first: exact name, then names that start with yours, then names containing every word you typed (e.g. `BCC Felsinea`). `province` narrows it to one province.
- `by_vat_number` - looks up each Partita IVA (e.g. `00159560366`). Several can go in `query`, separated by commas or new lines.
- `by_rea_number` - looks up each REA code with its chamber (e.g. `MO-187940`). A bare number takes its chamber from `province`.

**Direct company URLs** look like `https://www.ufficiocamerale.it/1295/bcc-felsinea-banca-di-credito-cooperativo-dal-1902-sc` and override `mode`/`query`.

**Batch list** (`identifiers`): VAT numbers, company names, REA codes and URLs mixed, one per line.

**Not supported:** the paid "ACQUISTA VISURA / ACQUISTA BILANCIO" documents and anything behind them (directors list, shareholders, insolvency detail, XBRL accounts). Those fields are returned as `null`.

### Use cases

| Team | What they build |
|------|----------------|
| **KYC / KYB compliance** | Verify company identity, legal form, VAT, status and registration before onboarding |
| **B2B sales & lead gen** | Prospect lists by name or keyword and province, with PEC and (add-on) website + email |
| **Credit & risk analysts** | Screen revenue, profit, share capital and filing status before extending credit |
| **Accounting & e-invoicing** | Bulk PEC certified emails and SDI codes for invoicing and formal correspondence |
| **Data enrichment** | Append Italian company attributes to CRM records using VAT as the join key |

### How it works

1. **Give a query, URLs or a batch list.** VAT numbers are checked against the Partita IVA check digit first.
2. **Each company is found through the site's own search** (VAT or name), or read straight from its URL. REA codes are resolved to candidate VAT numbers and kept only when the card's REA matches.
3. **Each page is fetched through an Italian residential IP** with a real browser fingerprint - the site refuses datacenter and non-Italian IPs. A challenged IP is replaced and the lookup retried; it is never read as "not found".
4. **The card is parsed**: registry fields, financials with their years, the PEC (decoded and cross-checked) and the SDI code.
5. **Optional enrichment**: the company's own website is looked for (the domain of its PEC, then its registered name as `.it` / `.com` domains), checked for proof of ownership, and a contact email is read from it.
6. **One row per company** is pushed, up to `maxItems`.

### Input configuration

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `mode` | string | `by_name` | `by_name`, `by_vat_number` or `by_rea_number` |
| `query` | string | - | Company name, VAT number(s) or REA code(s), matching `mode` |
| `province` | string | all of Italy | Two-letter province code (or name) to filter name searches; in REA mode, the chamber for a bare REA number |
| `directUrls` | array | - | ufficiocamerale.it company page URLs. Override `mode`/`query` |
| `identifiers` | array | - | Batch list: VAT numbers, names, REA codes, URLs, one per line |
| `maxMatchesPerName` | integer | `1` | Companies opened per name in the batch list (1-200) |
| `maxItems` | integer | `10` | Maximum company records delivered (and charged) in the run (1-10,000) |
| `maxConcurrency` | integer | `8` | Company pages fetched in parallel (1-16) |
| `onlyWithPec` | boolean | `false` | Skip companies without a PEC (not delivered, not charged) |
| `includePec` | boolean | `true` | Accepted for compatibility; INI-PEC asks for a CAPTCHA on every company search, so it is not used and `pec_source` is `page` or `null` |
| `enrichEmails` | boolean | `false` | Add the company's verified website and contact email ($0.0009 per verified website) |
| `proxyConfiguration` | object | RESIDENTIAL, Italy | Leave as is; the site answers Italian IPs only |

Provide `query`, `directUrls` or `identifiers`. An empty input runs the demo search (`BCC Felsinea`, by name).

**Search by name, filtered by province:**

```json
{ "mode": "by_name", "query": "BCC Felsinea", "province": "BO", "maxItems": 10 }
```

**Direct URL - when you already have the company link:**

```json
{ "directUrls": ["https://www.ufficiocamerale.it/1295/bcc-felsinea-banca-di-credito-cooperativo-dal-1902-sc"], "maxItems": 1 }
```

**Lookup by VAT number:**

```json
{ "mode": "by_vat_number", "query": "00602670556", "maxItems": 1 }
```

**Lookup by REA code:**

```json
{ "mode": "by_rea_number", "query": "VI-333040", "maxItems": 1 }
```

**A batch of VAT numbers, names and REA codes, companies with a PEC only, with website + email:**

```json
{
  "identifiers": ["00159560366", "IT01928950466", "Barilla G. e R. Fratelli", "TR-63492"],
  "onlyWithPec": true,
  "enrichEmails": true,
  "maxItems": 100
}
```

**A keyword and a province as a small directory** - up to 50 plumbers in Milan:

```json
{ "mode": "by_name", "query": "idraulico", "province": "MI", "maxItems": 50 }
```

### Output sample

A real row from a verification run of this actor (`{"mode": "by_vat_number", "query": "00602670556"}`, 2026-09-30) - the same company, and the same values, as the sample row other ufficiocamerale.it scrapers publish:

```json
{
  "vat_number": "00602670556",
  "tax_code": "00602670556",
  "rea_number": "TR-63492",
  "cciaa_chamber": "TR",
  "legal_name": "TERNINOX S.P.A.",
  "trade_name": null,
  "legal_form": "SOCIETA' PER AZIONI",
  "status": "attiva",
  "incorporation_date": "15/10/1991",
  "cessation_date": null,
  "share_capital_eur": 20800000,
  "share_capital_year": 2024,
  "registered_address": "VIALE B. BRIN 218 - 05100 - TERNI (TR)",
  "address_locality": "TERNI",
  "address_province": "TR",
  "address_postal_code": "05100",
  "ateco_code": "241",
  "ateco_description": "SIDERURGIA",
  "employees_count": 54,
  "employees_year": 2024,
  "revenue_eur": 124885370,
  "revenue_year": 2023,
  "profit_eur": -17218371,
  "profit_year": 2023,
  "pec_email": "terninox@pec.acciaiterni.info",
  "pec_source": "page",
  "phone": null,
  "website": null,
  "codice_destinatario": "YZW23AT",
  "amministratori": null,
  "soci": null,
  "has_filed_bilancio": true,
  "latest_bilancio_year": 2023,
  "bilancio_xbrl_url": null,
  "has_insolvency": null,
  "last_modification_date": null,
  "source_url": "https://www.ufficiocamerale.it/4527/terninox-spa",
  "scraped_at": "2026-09-30T03:15:24.910Z",
  "contact_email": null,
  "contact_website": null,
  "website_matched_by": null,
  "website_candidate": null,
  "emailEnrichment": null,
  "query": "00602670556",
  "query_type": "partita_iva",
  "name_match": null,
  "matched_listing_name": null,
  "pec_domain": "pec.acciaiterni.info",
  "pec_matches_structured_data": true,
  "codice_destinatario_as_published": "YZW23AT",
  "vat_number_eu": "IT00602670556",
  "vat_checksum_valid": true,
  "tax_code_masked": null,
  "legal_nature_code": "SP",
  "status_notice": null,
  "incorporation_date_iso": "1991-10-15",
  "address_street": "VIALE B. BRIN 218",
  "latitude": 42.56216,
  "longitude": 12.66911
}
```

With `enrichEmails` on - OBER ALP S.P.A. (VAT `00122250210`, PEC `info@pec.oberalp.it`) in a verification run, 2026-09-30:

```json
{
  "contact_email": "info@oberalp.it",
  "contact_website": "https://oberalp.com/",
  "website_matched_by": "company-number",
  "website_candidate": null,
  "emailEnrichment": {
    "status": "verified",
    "found_by": "domain-guess",
    "pages_checked": 4,
    "additional_emails": ["at_customerservice@oberalp.com", "polska@oberalp.com", "salewa.czech@oberalp.com", "customerservice.uk@oberalp.com"],
    "email_mx_verified": true,
    "email_confidence": "high"
  }
}
```

The site's legal notice prints the company's VAT number (`company-number`); `info@oberalp.it` leads because it is a general inbox on the domain of the company's own PEC.

### Output fields

**Identity**

| Field | Type | Description |
|-------|------|-------------|
| `vat_number` | string | Partita IVA |
| `tax_code` | string | Codice fiscale when the card prints it in full (companies) |
| `rea_number` | string | REA number with chamber prefix (e.g. `TR-63492`) |
| `cciaa_chamber` | string | Camera di Commercio province code |
| `legal_name` | string | Denominazione / ragione sociale |
| `trade_name` | string | Always `null` (the free card has no separate trading name) |
| `legal_form` | string | Forma giuridica as printed |
| `status` | string | `attiva` or `cessata` |
| `incorporation_date` | string | Registration date (DD/MM/YYYY) |
| `cessation_date` | string | Always `null` (the card marks a company `cessata` but prints no date) |

**Address**

| Field | Type | Description |
|-------|------|-------------|
| `registered_address` | string | Sede legale as printed |
| `address_locality` | string | City / comune |
| `address_province` | string | Province code |
| `address_postal_code` | string | CAP (`null` when the card leaves it empty) |

**Classification & financials**

| Field | Type | Description |
|-------|------|-------------|
| `ateco_code` / `ateco_description` | string | Activity code and description |
| `employees_count` / `employees_year` | number | Employees and the year beside them |
| `revenue_eur` / `revenue_year` | number | Fatturato and its year |
| `profit_eur` / `profit_year` | number | Utile (negative = loss) and its year; `null` when the card prints a zero with no accounts on record |
| `share_capital_eur` / `share_capital_year` | number | Capitale sociale and its year |
| `has_filed_bilancio` | boolean | `true` when the card offers filed accounts (a bilancio) for sale, i.e. accounts are on record |
| `latest_bilancio_year` | number | Year of the latest accounts' figures |
| `amministratori`, `soci`, `has_insolvency`, `bilancio_xbrl_url` | - | Always `null`: paid visure on the site |

**Contact & e-invoicing**

| Field | Type | Description |
|-------|------|-------------|
| `pec_email` | string | PEC certified email, exactly as the card publishes it |
| `pec_source` | string | `page` when read from the card, otherwise `null` |
| `codice_destinatario` | string | SDI code for e-invoicing (`null` for the `0000000` default) |
| `phone` / `website` | string | Always `null`: the free card publishes neither (use `enrichEmails`) |
| `contact_email` / `contact_website` | string | With `enrichEmails`: the company's own website and an email read from it |
| `website_matched_by` | string | With `enrichEmails`: `company-number` (a page shows the company's codice fiscale or Partita IVA), `postcode` (registered postcode and town) or `registered-name` (legal name with legal form) |
| `website_candidate` | string | With `enrichEmails`: a site found by name that showed none of those - probably another business with a similar name; no email is taken from it and it is not charged |
| `emailEnrichment` | object | With `enrichEmails`: `status`, `found_by` (`pec-domain` or `domain-guess`), `pages_checked`, `additional_emails`, `email_mx_verified`, `email_confidence` |
| `source_url` / `scraped_at` | string | The company page read, and when |

**Extra fields**

| Field | Description |
|-------|-------------|
| `query` / `query_type` | Your input, and `partita_iva`, `codice_fiscale`, `company_name`, `rea_number` or `url` |
| `name_match` / `matched_listing_name` | Name searches: `exact`, `startsWith` or `allWords`, and the name as the result list printed it |
| `pec_domain` / `pec_matches_structured_data` | Domain of the PEC; `true` when the visible PEC equals the page's schema.org email |
| `codice_destinatario_as_published` | The SDI code exactly as printed, including `0000000` |
| `vat_number_eu` / `vat_checksum_valid` | IT-prefixed VAT, and the Partita IVA check-digit result |
| `tax_code_masked` | Sole traders: the owner's codice fiscale as the card masks it (`DLSRSL*****E131N`) |
| `legal_nature_code` | The site's short legal-nature code (`SP`, `SR`, `SN`, `DI` ...) |
| `status_notice` / `incorporation_date_iso` | The card's `Cessata` notice; registration date as `YYYY-MM-DD` |
| `address_street` / `latitude` / `longitude` | Street part of the address and the card's map pin (`null` when missing or outside Italy) |

### Measured coverage

Field fill of the company card, measured on three samples (`n` = companies read):

| | 30 random pages from the site's own sitemap | 40 VAT numbers printed on Italian company websites | 27 pages - 24 small businesses (19 sole traders) + 3 large firms |
|---|---|---|---|
| active / cessata | 29 / 1 | 39 / 1 | 17 / 10 |
| **PEC, active companies** | **28 / 29** | **38 / 39** | **12 / 17** |
| PEC, ceased companies | 0 / 1 | 0 / 1 | 0 / 10 |
| SDI code (not `0000000`) | 22 / 30 | 29 / 40 | 6 / 27 |
| legal form, ATECO, employees | 28 / 30 | 38 / 40 | 20 / 27 |
| revenue / profit / share capital | 18 / 18 / 19 | 24 / 25 / 26 | 5 / 5 / 6 |
| postal code / map pin | 29 / 29 | 38 / 38 | 23 / 27 |

An active company publishes its PEC on its card **71% to 97%** of the time depending on the mix (sole traders less often); a ceased one did in none of 12.

**`enrichEmails`**, measured in verification runs on the first two samples (2026-09-30):

| | 30 random sitemap companies | 35 companies known to have a website |
|---|---|---|
| verified website | **9** (30%) | **12** (34%) |
| ...of which with a contact email | 4 | 8 |
| unverified `website_candidate` only | 11 | 13 |
| how the verified sites were proven | 7 VAT/tax code, 1 postcode, 1 registered name | 12 VAT/tax code |

Every verified site was checked by hand: each is the company's own site or its group's site. A website whose domain comes from neither the company's registered name nor its PEC (a brand or shop name) is not found; that is what `website_candidate` and the rates above reflect.

Speed (verification runs, default settings): 5 companies by VAT number in 5 seconds, 35 in 15 seconds; with `enrichEmails`, 30 companies in 174 seconds.

### Pricing

**$0.10 per run + $0.001 per company record.** Optional add-on: **$0.0009** per company delivered with a verified website.

| Outcome | Charged |
|---|---|
| Run starts | $0.10 (once per run) |
| Company found and delivered (with or without a PEC) | $0.001 |
| Company skipped by `onlyWithPec` | no |
| VAT number, name or REA the site does not know | no |
| Invalid VAT number (fails the check digit) | no - never fetched |
| Unreachable after retries | no |
| The same company twice in your input | charged once |
| `enrichEmails`: verified website attached | +$0.0009 |
| `enrichEmails`: only an unverified `website_candidate`, or nothing found | no |

Examples: 10 companies = $0.11; 1,000 companies = $1.10; 1,000 companies with `enrichEmails` at the ~30% verified-website rate measured above = about $1.37. `maxItems` caps what one run can charge.

### Run summary

Each run writes `RUN_SUMMARY` to its key-value store: delivered vs charged, name-search totals (results the site reported, openable companies, queued), each REA lookup (candidates checked, the one verified), enrichment statistics, and every lookup that did not produce a record, each in its own list - `invalidInput` (with the reason), `notFound`, `skippedNoPec`, `unreachable` (with the last error).

### FAQ

**How do I search Italian companies by name?**
Set `mode` to `by_name` and put the name in `query`. Add `province` to narrow it. The best matches come first: exact name, then names starting with yours, then names containing every word. Some listings on the site carry no VAT number and cannot be opened (58 of 451 results for `enel` in Rome); they are counted in the run summary.

**Can I look a company up by VAT number (Partita IVA)?**
Yes - `by_vat_number`, or VAT numbers in `identifiers`. Every VAT is looked up through the site's own search, so it works whatever the company's page address is. `IT` prefixes, spaces and dots are fine.

**Can I look a company up by REA number?**
Yes - `by_rea_number` with the chamber, e.g. `MO-187940` (or a bare number plus `province`). The site's own search does not accept REA numbers, so the actor finds candidate VAT numbers published next to that REA on the web and delivers a company only when its own card carries the same chamber and REA. A REA that no web page links to a VAT number is reported as `notFound` and not charged.

**What is PEC and why does it matter?**
PEC (Posta Elettronica Certificata) is Italy's certified email, legally equivalent to registered post. Every Italian company must file one with the Registro Imprese. The actor reads it from the company page and confirms it against the page's structured data.

**Does it use INI-PEC when the page has no PEC?**
No. `includePec` is accepted, but INI-PEC (inipec.gov.it) asks for a CAPTCHA on every company search, so it is not queried. `pec_source` is `page` or `null`.

**Which fields are always null?**
`amministratori`, `soci`, `has_insolvency` and `bilancio_xbrl_url` sit behind the site's paid visura/bilancio; `trade_name`, `cessation_date`, `last_modification_date`, `phone` and `website` are not printed on the free card. With `enrichEmails`, the company's website and email come in `contact_website` / `contact_email`.

**Do I need to configure proxies?**
No. The default is Apify RESIDENTIAL with country Italy, which the site requires. If another setting is refused, the run switches to it by itself.

**How many companies can I get per run?**
Up to 10,000 via `maxItems`.

**Why is a company I know missing?**
Check `RUN_SUMMARY`: `notFound` (the site has no card for it), `invalidInput` (the VAT fails the check digit), `skippedNoPec` (with `onlyWithPec`) or `unreachable` (re-run just those).

### Run it from code

```bash
curl -X POST "https://api.apify.com/v2/acts/scrapersdelight~it-company-pec-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "mode": "by_vat_number", "query": "00159560366, 01928950466" }'
```

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('scrapersdelight/it-company-pec-scraper').call({ identifiers: ['00159560366', 'Barilla G. e R. Fratelli'] });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

```python
from apify_client import ApifyClient
client = ApifyClient("YOUR_TOKEN")
run = client.actor("scrapersdelight/it-company-pec-scraper").call(run_input={"mode": "by_vat_number", "query": "00159560366"})
items = client.dataset(run["defaultDatasetId"]).list_items().items
```

### For AI agents & LLM apps

- **Purpose:** Italian company registry data (VAT, REA, ATECO, financials, PEC, SDI code) from ufficiocamerale.it.
- **Minimal input:** `{ "mode": "by_name", "query": "BCC Felsinea", "maxItems": 5 }` or `{ "mode": "by_vat_number", "query": "00159560366" }`.
- **Output:** flat JSON rows. Key fields: `vat_number`, `tax_code`, `rea_number`, `cciaa_chamber`, `legal_name`, `legal_form`, `status`, `registered_address`, `ateco_code`, `employees_count`, `revenue_eur`, `profit_eur`, `share_capital_eur`, `pec_email`, `pec_source`, `codice_destinatario`, `source_url`.
- **Billing:** $0.10 per run + $0.001 per company record; `enrichEmails` adds $0.0009 per record with a verified website.
- **Always null:** `amministratori`, `soci`, `has_insolvency`, `bilancio_xbrl_url` (paid visure).

# Actor input Schema

## `mode` (type: `string`):

How to read the Search query. by_name searches the company name on the site (best matches first, narrowed by Province). by_vat_number looks each Partita IVA up through the site's own search, so every VAT number works, not only ones that appear in a page address. by_rea_number resolves a REA code (e.g. MO-187940) to its company and keeps it only when the company's own card carries that REA.

## `query` (type: `string`):

Company name (e.g. BCC Felsinea), VAT number (e.g. 00159560366) or REA code (e.g. MO-187940), matching the selected mode. In VAT and REA modes you can put several, separated by commas or new lines.

## `province` (type: `string`):

Optional two-letter Italian province code to filter name-search results (e.g. MI, RM, BO, NA); the province name also works. In REA mode it is used as the chamber of commerce for a REA number given without one.

## `directUrls` (type: `array`):

Exact ufficiocamerale.it company page URLs (e.g. https://www.ufficiocamerale.it/1295/bcc-felsinea-banca-di-credito-cooperativo-dal-1902-sc). Overrides mode/query.

## `identifiers` (type: `array`):

Optional: many lookups in one run, one per line, mixed freely - 11-digit Partita IVA numbers (checked against the P.IVA check digit before anything is fetched), company names, REA codes like TR-63492, or ufficiocamerale.it company URLs. Used together with mode/query or directUrls.

## `maxMatchesPerName` (type: `integer`):

For each company NAME in the batch list, how many matching companies to open, best match first (exact name, then names that start with it, then names containing every word). A name in Search query opens up to Maximum companies instead.

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

Hard cap on the number of company records delivered (and charged) in this run.

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

Maximum number of company pages fetched in parallel, each on its own Italian residential IP.

## `onlyWithPec` (type: `boolean`):

On: companies whose card publishes no PEC are skipped - not delivered and not charged - and the run keeps going until Maximum companies records WITH a PEC are delivered or the matches run out. Off: every company found is delivered.

## `includePec` (type: `boolean`):

Accepted for compatibility. INI-PEC (inipec.gov.it) asks for a CAPTCHA on every company search, so it is not queried: pec_email comes from the company page (pec_source = page) or is null. No extra charge either way.

## `enrichEmails` (type: `boolean`):

When on, each company's own website is looked for (the domain of its PEC, then its registered name as .it / .com domains) to attach contact_email, contact_website and an emailEnrichment object. A website counts only when one of its pages shows the company's codice fiscale or Partita IVA, its registered postcode next to its town, or its registered name with its legal form; website_matched_by says which, and an unconfirmed site goes to website_candidate with no email taken from it. Adds a few seconds per record and is charged per record with a verified website.

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

ufficiocamerale.it answers Italian IPs only (datacenter and non-Italian IPs are refused by its Cloudflare), so the default is Apify RESIDENTIAL with country Italy. If another setting is refused with no success, the run switches to RESIDENTIAL Italy by itself.

## Actor input object example

```json
{
  "mode": "by_name",
  "query": "BCC Felsinea",
  "maxMatchesPerName": 1,
  "maxItems": 10,
  "maxConcurrency": 8,
  "onlyWithPec": false,
  "includePec": true,
  "enrichEmails": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "IT"
  }
}
```

# Actor output Schema

## `records` (type: `string`):

Registry identity, address, activity, financials, PEC and SDI code per company, in memo23-compatible field names.

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

Delivered vs charged, name-search and REA-lookup details, enrichment statistics, and the kinds of nothing: invalid input, not found, skipped without PEC, unreachable.

# 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 = {
    "query": "BCC Felsinea",
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "IT"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapersdelight/it-company-pec-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 = {
    "query": "BCC Felsinea",
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "IT",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("scrapersdelight/it-company-pec-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 '{
  "query": "BCC Felsinea",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "IT"
  }
}' |
apify call scrapersdelight/it-company-pec-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapersdelight/it-company-pec-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/3I2IbTHDZfKIAtJMK/builds/NODi0DHNMamxezmTr/openapi.json
