# Cold Email Law Checker (`phaz/cold-email-law-checker`) Actor

Checks every lead against the cold email law of the recipient's country before you send. 33 countries checked against the law text: whether a first email needs consent for a named person, info@ or gmail address, what the email must contain, and a link to the law.

- **URL**: https://apify.com/phaz/cold-email-law-checker.md
- **Developed by:** [Ilia Ivanov](https://apify.com/phaz) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-usage

## 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

## Cold Email Law Checker

Before you send a cold email campaign to another country, check whether the law there lets you. This Actor gives every lead in your list a verdict for the **first unsolicited marketing email** to it, based on the recipient's country and the kind of address.

33 countries, each checked against the law text or the regulator's guidance, with a link to the source.

### Why

The rules change at every border. Germany, Spain and Italy want consent before the first email, even to a company address. France allows it if the offer relates to the person's job. The US allows it but wants a postal address and an opt-out in every email. Sweden protects people but not companies. Slovakia, Slovenia and Japan care whether the company published the address itself.

Email verifiers tell you whether an address exists. This tells you whether you may write to it.

### What you get for each lead

| Field | Example |
|---|---|
| `law_country` | `DE` |
| `law_addressType` | `named`, `generic` (info@, sales@) or `personal` (gmail) |
| `law_verdict` | `ok`, `cond`, `consent` or `unknown` |
| `law_verdictLabel` | `Consent first` |
| `law_sendWithoutConsent` | `false` |
| `law_reason` | `Prior consent required in Germany for this kind of address.` |
| `law_rule` | The rule in one paragraph |
| `law_mustInclude` | What the email itself must contain (opt-out, postal address...) |
| `law_lawSource` | Link to the law or the regulator |
| `law_rulesPage` | Page with all verdicts and sources for that country |
| `law_checked` | Date the rules were checked |

Your own fields are kept, so you can filter the dataset and send only the rows you may email. The run summary (counts per verdict) is saved as `OUTPUT` in the key-value store.

### Input

Give it leads in one of three ways:

- **Dataset ID** from another Actor run, such as a lead scraper. Nested fields like `location.country` are found automatically.
- **CSV URL** of an export.
- **Leads** as JSON: plain email addresses or objects.

The email, country and source fields are detected automatically. You can set them by name if detection picks the wrong one.

**Use the person's country, not the company HQ.** The rules follow the recipient: a German employee of a US company is a German recipient. If no country is given, it is guessed from the domain (.de, .fr) and the row says so.

**Optional source field.** `published` (the company put the address on its own site or in a register) or `vendor` (a tool found or guessed it; values like `apollo` or `hunter` count as vendor). In Canada, Australia, Japan, the Netherlands, Slovakia and Slovenia this changes the verdict.

### Run it automatically after your lead scraper

1. Open the lead scraper you already use (or your saved task for it) and go to the **Integrations** tab.
2. Choose **Connect Actor or Task**, pick **Cold Email Law Checker**, and trigger it when the run succeeds.
3. Keep the prefilled input: `{"datasetId": "{{resource.defaultDatasetId}}"}`. Add `countryField` or `sourceField` if your scraper names them differently.

Every new list then gets its verdicts without you touching it. The checker only gets read access to that one dataset.

### Countries covered

| Country | Named person (jane@company) | Generic (info@company) | Personal mailbox (gmail) | Checked |
|---|---|---|---|---|
| [Australia](https://phazww.github.io/can-i-cold-email/c/australia.html) | Specific cases | Specific cases | Specific cases | 2026-10-10 |
| [Austria](https://phazww.github.io/can-i-cold-email/c/austria.html) | Consent first | Consent first | Consent first | 2026-10-10 |
| [Belgium](https://phazww.github.io/can-i-cold-email/c/belgium.html) | Consent first | No consent needed | Consent first | 2026-10-10 |
| [Bulgaria](https://phazww.github.io/can-i-cold-email/c/bulgaria.html) | Specific cases | Specific cases | Specific cases | 2026-10-14 |
| [Canada](https://phazww.github.io/can-i-cold-email/c/canada.html) | Specific cases | Specific cases | Consent first | 2026-10-10 |
| [Croatia](https://phazww.github.io/can-i-cold-email/c/croatia.html) | Not verified | No consent needed | Consent first | 2026-10-14 |
| [Cyprus](https://phazww.github.io/can-i-cold-email/c/cyprus.html) | Not verified | Not verified | Consent first | 2026-10-14 |
| [Czech Republic](https://phazww.github.io/can-i-cold-email/c/czech-republic.html) | Consent first | Consent first | Consent first | 2026-10-10 |
| [Denmark](https://phazww.github.io/can-i-cold-email/c/denmark.html) | Consent first | Consent first | Consent first | 2026-10-10 |
| [Estonia](https://phazww.github.io/can-i-cold-email/c/estonia.html) | Not verified | No consent needed | Consent first | 2026-10-14 |
| [Finland](https://phazww.github.io/can-i-cold-email/c/finland.html) | Not verified | No consent needed | Consent first | 2026-10-10 |
| [France](https://phazww.github.io/can-i-cold-email/c/france.html) | No consent needed | No consent needed | Not verified | 2026-10-10 |
| [Germany](https://phazww.github.io/can-i-cold-email/c/germany.html) | Consent first | Consent first | Consent first | 2026-10-10 |
| [Greece](https://phazww.github.io/can-i-cold-email/c/greece.html) | Consent first | Consent first | Consent first | 2026-10-14 |
| [Ireland](https://phazww.github.io/can-i-cold-email/c/ireland.html) | Specific cases | No consent needed | Consent first | 2026-10-10 |
| [Italy](https://phazww.github.io/can-i-cold-email/c/italy.html) | Consent first | Consent first | Consent first | 2026-10-10 |
| [Japan](https://phazww.github.io/can-i-cold-email/c/japan.html) | Specific cases | Specific cases | Specific cases | 2026-10-15 |
| [Latvia](https://phazww.github.io/can-i-cold-email/c/latvia.html) | Not verified | No consent needed | Consent first | 2026-10-14 |
| [Liechtenstein](https://phazww.github.io/can-i-cold-email/c/liechtenstein.html) | Consent first | Consent first | Consent first | 2026-10-14 |
| [Luxembourg](https://phazww.github.io/can-i-cold-email/c/luxembourg.html) | Not verified | No consent needed | Consent first | 2026-10-14 |
| [Malta](https://phazww.github.io/can-i-cold-email/c/malta.html) | Consent first | Consent first | Consent first | 2026-10-14 |
| [Netherlands](https://phazww.github.io/can-i-cold-email/c/netherlands.html) | Specific cases | Specific cases | Consent first | 2026-10-10 |
| [Norway](https://phazww.github.io/can-i-cold-email/c/norway.html) | Consent first | No consent needed | Consent first | 2026-10-10 |
| [Poland](https://phazww.github.io/can-i-cold-email/c/poland.html) | Consent first | Consent first | Consent first | 2026-10-10 |
| [Portugal](https://phazww.github.io/can-i-cold-email/c/portugal.html) | Not verified | No consent needed | Consent first | 2026-10-11 |
| [Singapore](https://phazww.github.io/can-i-cold-email/c/singapore.html) | No consent needed | No consent needed | No consent needed | 2026-10-15 |
| [Slovakia](https://phazww.github.io/can-i-cold-email/c/slovakia.html) | Specific cases | Specific cases | Specific cases | 2026-10-14 |
| [Slovenia](https://phazww.github.io/can-i-cold-email/c/slovenia.html) | Specific cases | No consent needed | Consent first | 2026-10-14 |
| [Spain](https://phazww.github.io/can-i-cold-email/c/spain.html) | Consent first | Consent first | Consent first | 2026-10-10 |
| [Sweden](https://phazww.github.io/can-i-cold-email/c/sweden.html) | No consent needed | No consent needed | Consent first | 2026-10-10 |
| [Switzerland](https://phazww.github.io/can-i-cold-email/c/switzerland.html) | Consent first | Consent first | Consent first | 2026-10-10 |
| [United Kingdom](https://phazww.github.io/can-i-cold-email/c/united-kingdom.html) | No consent needed | No consent needed | Consent first | 2026-10-10 |
| [United States](https://phazww.github.io/can-i-cold-email/c/united-states.html) | No consent needed | No consent needed | No consent needed | 2026-10-10 |

Not covered yet: everything else. Rows for other countries come back as `unknown` with the reason.

### Limits

This is a research summary, not legal advice. It covers the first unsolicited marketing email to a business recipient. Data protection law (GDPR, UK GDPR) applies separately whenever an address identifies a person. Every verdict links to its source so you can check it.

The same rules power the free web checker at [phazww.github.io/can-i-cold-email](https://phazww.github.io/can-i-cold-email/). Corrections are welcome: open an issue on [GitHub](https://github.com/phazww/cold-email-law-checker).

# Actor input Schema

## `leads` (type: `array`):

Email addresses, or objects such as {"email": "jane@acme.de", "countryCode": "DE", "source": "apollo"}. Ignored when a dataset ID or CSV URL is given.

## `datasetId` (type: `string`):

Check the output of another Actor run, for example a lead scraper. Nested fields such as location.country are found automatically. The Actor gets read access to this dataset only.

## `csvUrl` (type: `string`):

A public link to a CSV export. The first row must be the header.

## `emailField` (type: `string`):

Leave empty to detect it. Example: workEmail.

## `countryField` (type: `string`):

Where the person is, not where the company is headquartered. Leave empty to detect it. Example: location.country.

## `sourceField` (type: `string`):

Optional. Values like published or company website vs. vendor, apollo or hunter. In Canada, Australia, Japan, the Netherlands, Slovakia and Slovenia the verdict depends on it.

## `defaultCountry` (type: `string`):

Two-letter code used when the country is unknown and the domain does not tell it, for example US.

## `keepOriginalFields` (type: `boolean`):

Output every input field plus the verdict fields (prefixed law\_).

## `maxLeads` (type: `integer`):

0 means no limit.

## Actor input object example

```json
{
  "leads": [
    {
      "email": "info@example.de",
      "countryCode": "DE"
    },
    {
      "email": "jan.novak@example.sk",
      "countryCode": "SK",
      "source": "company website"
    },
    {
      "email": "tom.baker@example.co.uk",
      "countryCode": "GB"
    },
    {
      "email": "lisa.chen@example.com",
      "countryCode": "US"
    }
  ],
  "keepOriginalFields": true,
  "maxLeads": 0
}
```

# Actor output Schema

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

No description

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

No description

# 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 = {
    "leads": [
        {
            "email": "info@example.de",
            "countryCode": "DE"
        },
        {
            "email": "jan.novak@example.sk",
            "countryCode": "SK",
            "source": "company website"
        },
        {
            "email": "tom.baker@example.co.uk",
            "countryCode": "GB"
        },
        {
            "email": "lisa.chen@example.com",
            "countryCode": "US"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("phaz/cold-email-law-checker").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 = { "leads": [
        {
            "email": "info@example.de",
            "countryCode": "DE",
        },
        {
            "email": "jan.novak@example.sk",
            "countryCode": "SK",
            "source": "company website",
        },
        {
            "email": "tom.baker@example.co.uk",
            "countryCode": "GB",
        },
        {
            "email": "lisa.chen@example.com",
            "countryCode": "US",
        },
    ] }

# Run the Actor and wait for it to finish
run = client.actor("phaz/cold-email-law-checker").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 '{
  "leads": [
    {
      "email": "info@example.de",
      "countryCode": "DE"
    },
    {
      "email": "jan.novak@example.sk",
      "countryCode": "SK",
      "source": "company website"
    },
    {
      "email": "tom.baker@example.co.uk",
      "countryCode": "GB"
    },
    {
      "email": "lisa.chen@example.com",
      "countryCode": "US"
    }
  ]
}' |
apify call phaz/cold-email-law-checker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,phaz/cold-email-law-checker"
        }
    }
}
```

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/We1kBh5uDitm06W7y/builds/Zt5G71mycAfh3FBHU/openapi.json
