PHPackages                             emailsherlock/email-guard-core - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Mail &amp; Notifications](/categories/mail)
4. /
5. emailsherlock/email-guard-core

ActiveLibrary[Mail &amp; Notifications](/categories/mail)

emailsherlock/email-guard-core
==============================

Email-Guard core library for PHP: local email checks (syntax, reserved TLDs, disposable domains) plus optional escalation to the EmailSherlock Verify API.

v0.4.0(3w ago)07.2k1MITPHPPHP &gt;=8.1CI passing

Since Jun 12Pushed 3w agoCompare

[ Source](https://github.com/Emailsherlock1/email-guard-core-php)[ Packagist](https://packagist.org/packages/emailsherlock/email-guard-core)[ Docs](https://github.com/Emailsherlock1/email-guard-core-php)[ RSS](/packages/emailsherlock-email-guard-core/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (1)Dependencies (8)Versions (7)Used By (1)

email-guard-core (PHP)
======================

[](#email-guard-core-php)

Reference implementation of [email-guard-spec](https://github.com/Emailsherlock1/email-guard-spec): a guard for the email field of your signup form, checkout, or any form where a fake address costs real money.

Without an API key it blocks what it can prove locally: broken syntax, reserved TLDs (`deleted+user274@deleted.invalid` is syntactically fine and still junk), and 73k+ known disposable domains from the bundled snapshot. Zero network calls, zero latency. An [EmailSherlock API key](https://emailsherlock.com/api/docs)adds the data unlock: live MX, SMTP probe, a fresh disposable list, role and catch-all detection.

No framework dependency. The Symfony bundle and the WordPress plugin build on this library; use it directly anywhere PHP 8.1+ runs.

Install
-------

[](#install)

```
composer require emailsherlock/email-guard-core
```

Use
---

[](#use)

```
use Emailsherlock\EmailGuard\EmailGuard;

$guard = new EmailGuard();              // local checks only
$result = $guard->check($email);

if ($result->isDenied()) {
    // reject the form field
}
```

With an API key and a policy:

```
$guard = new EmailGuard([
    'api_key'   => getenv('EMAILSHERLOCK_API_KEY'),
    'block_on'  => ['invalid', 'disposable'],   // default
    'review_on' => ['catch_all'],               // hold for confirmation
]);

$result = $guard->check($email);

match ($result->action) {
    Action::Allow  => $this->accept(),
    Action::Deny   => $this->reject($result->reasons),
    Action::Review => $this->requireEmailConfirmation(),
};
```

What you get back
-----------------

[](#what-you-get-back)

Every check returns a `Result` with four spec-defined fields:

FieldTypeMeaning`verdict``Verdict``valid`, `invalid`, `disposable`, `role`, `catch_all`, `unknown``action``Action``allow`, `deny`, `review`, resolved from your policy`reasons``string[]`machine-readable codes, e.g. `reserved_tld`, `mailbox_not_found``degraded``bool`true when the API was wanted but unreachablePlus `apiCalled` and `apiResponse` (the raw Verify API payload, informational).

Configuration
-------------

[](#configuration)

KeyDefaultNotes`api_key``null`null disables the remote check entirely`block_on``['invalid', 'disposable']`verdicts that deny`review_on``[]`verdicts that flag for a second gate`fail_open``true`an API outage lets addresses through, never blocks them`timeout_ms``800`total budget for the API call`base_url``https://api.emailsherlock.com`override for testingPolicy is yours: the guard reports verdicts, your `block_on` decides what a deny is. The defaults block provable junk and let everything debatable (role addresses, catch-all domains, unknowns) through.

**Fail-open is the default on purpose.** A blocked legitimate customer costs more than a leaked junk signup. If the API is unreachable, the local checks keep working and the rest passes with `degraded: true`. Set `'fail_open' => false` if your form prefers to reject on outage.

Custom HTTP client
------------------

[](#custom-http-client)

The default transport uses ext-curl. To route the API call through your own PSR-18 client:

```
use Emailsherlock\EmailGuard\Http\Psr18Transport;

$guard = new EmailGuard(
    ['api_key' => $key],
    new Psr18Transport($psr18Client, $requestFactory, $streamFactory),
);
```

PSR-18 carries no per-request timeout, so configure the budget on the client itself.

Decision telemetry (optional)
-----------------------------

[](#decision-telemetry-optional)

With an API key you can report decisions back so the account owner sees what the guard blocks (email-guard-spec section 11). Pass a `GuardReporter` to the guard; it records one event per check, and you flush the batch after the response is sent (the Symfony bundle wires this to `kernel.terminate`):

```
use Emailsherlock\EmailGuard\GuardReporter;

$reporter = new GuardReporter(apiKey: $key, integration: 'my-app');
$guard = new EmailGuard(['api_key' => $key], reporter: $reporter);

$guard->check($email);   // records automatically
// ... after the response:
$reporter->flush();      // batched POST /v1/guard/events
```

Key-gated (no key, no telemetry), fail-silent (a reporting failure never breaks or slows the host), and it sends the domain only, never the address.

Conformance
-----------

[](#conformance)

The test suite runs every vector from [email-guard-spec](https://github.com/Emailsherlock1/email-guard-spec)(vendored under `tests/vectors/`, synced via `tests/update-vectors.sh`). The same vectors run against every Email-Guard core library, so `.invalid`gets blocked bit-identically in PHP and in every other language.

```
composer test
```

Data
----

[](#data)

`data/disposable-snapshot.json.gz` is embedded from a pinned release of [email-guard-data](https://github.com/Emailsherlock1/email-guard-data), refreshed per core-lib release (`php bin/build-snapshot.php`). Matching is exact, same as the API's live list: the local check never blocks an address the API would let pass.

License
-------

[](#license)

MIT, see [LICENSE](LICENSE).

###  Health Score

44

—

FairBetter than 90% of packages

Maintenance94

Actively maintained with recent releases

Popularity26

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity37

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~3 days

Total

6

Last Release

27d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/a3a353e879e2fe9677d4575d87d7980fca9f2236be38bfa172d422ef7f12059f?d=identicon)[matthiastosch](/maintainers/matthiastosch)

---

Top Contributors

[![matthiastosch](https://avatars.githubusercontent.com/u/12081225?v=4)](https://github.com/matthiastosch "matthiastosch (6 commits)")

---

Tags

emailform validationsignupdisposableemail validationemail-verificationemailsherlock

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/emailsherlock-email-guard-core/health.svg)

```
[![Health](https://phpackages.com/badges/emailsherlock-email-guard-core/health.svg)](https://phpackages.com/packages/emailsherlock-email-guard-core)
```

###  Alternatives

[daveearley/daves-email-validation-tool

An easy to use, accurate-ish &amp; extensible email validation library for PHP 7+

284345.7k2](/packages/daveearley-daves-email-validation-tool)[propaganistas/laravel-disposable-email

Disposable email validator

6023.0M7](/packages/propaganistas-laravel-disposable-email)[mattketmo/email-checker

Throwaway email detection library

2752.1M5](/packages/mattketmo-email-checker)[stymiee/email-validator

A robust PHP 7.4+ email validation library that extends beyond basic validation with MX record checks, disposable email detection, and free email provider validation. Features include strict typing, custom validator support, internationalization (i18n), and an extensible architecture. Perfect for applications requiring thorough email verification with customizable validation rules.

33487.3k1](/packages/stymiee-email-validator)[vboctor/disposable_email_checker

Library to detect disposable email addresses

47108.1k3](/packages/vboctor-disposable-email-checker)[erag/laravel-disposable-email

A Laravel package to detect and block disposable email addresses.

254168.5k](/packages/erag-laravel-disposable-email)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
