PHPackages                             elliotjreed/haveibeenpwned - 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. [Security](/categories/security)
4. /
5. elliotjreed/haveibeenpwned

ActiveLibrary[Security](/categories/security)

elliotjreed/haveibeenpwned
==========================

PHP

4.0.1(3w ago)570.7k↓48.8%2[1 PRs](https://github.com/elliotjreed/haveibeenpwned/pulls)MITPHPPHP ^8.4CI passing

Since Apr 22Pushed 2w ago1 watchersCompare

[ Source](https://github.com/elliotjreed/haveibeenpwned)[ Packagist](https://packagist.org/packages/elliotjreed/haveibeenpwned)[ Docs](https://github.com/elliotjreed/haveibeenpwned)[ RSS](/packages/elliotjreed-haveibeenpwned/feed)WikiDiscussions master Synced 2w ago

READMEChangelogDependencies (10)Versions (11)Used By (0)

[![Contributor Covenant](https://camo.githubusercontent.com/2757a9db291c5ceda172e31d4fa5f3c4048a6e6257ee0b7113f80de277074b91/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f436f6e7472696275746f72253230436f76656e616e742d76322e3025323061646f707465642d6666363962342e737667)](code-of-conduct.md)

Have I Been Pwned PHP
=====================

[](#have-i-been-pwned-php)

PHP 8.4 or above is required.

For PHP 8.2 and 8.3 please use 3.0.0. For PHP 8.1 please use 2.0.0. For PHP 7.4 to 8.0 please use version 1.2.0.

See [CHANGELOG.md](CHANGELOG.md) for a full history of changes between versions.

Usage
-----

[](#usage)

Most methods require a Have I Been Pwned API key, obtained on a monthly subscription basis:

HIBP has three subscription tiers - **Core**, **Pro** and **High RPM** - and a handful of endpoints are restricted to Pro and above regardless of tier. See [Plan-specific features](https://haveibeenpwned.com/API/v3#PlanSpecificFeatures) and the [pricing page](https://haveibeenpwned.com/Subscription) for full details. A few endpoints (breach sources, a single breach, the latest breach, data classes, and Pwned Passwords) are public and need no API key at all. Each method below states what it requires; the table is a quick reference and the sections beneath it show full usage examples.

MethodRequiresReturns`BreachedAccount::breaches()`API key (Core tier or above)`Entity\Breach[]``BreachedAccount::breachNames()`API key (Core tier or above)`string[]``BreachedAccount::count()`API key (Core tier or above)`int``BreachedAccount::isBreached()`API key (Core tier or above)`bool``BreachedAccount::breachNamesByHashRange()`API key, **Pro tier or above**`string[]``Breaches::allSources()`none (public)`Entity\Breach[]``Breaches::byDomain()`none (public)`Entity\Breach[]``Breaches::bySourceName()`none (public)`?Entity\Breach``Breaches::latest()`none (public)`?Entity\Breach``Password::count()`none (public)`int``Password::isPwned()`none (public)`bool``PastedAccount::pastes()`API key (Core tier or above)`Entity\Paste[]``DataClasses::all()`none (public)`string[]``BreachedDomain::search()`API key (Core tier or above) + verified domain`array``SubscribedDomains::all()`API key (Core tier or above)`Entity\SubscribedDomain[]``StealerLog::byEmail()`API key, **Pro tier or above**, + verified domain`string[]``StealerLog::byWebsiteDomain()`API key, **Pro tier or above**, + verified domain`string[]``StealerLog::byEmailDomain()`API key, **Pro tier or above**, + verified domain`array``Subscription::status()`API key (Core tier or above)`Entity\SubscriptionStatus``DomainVerification::generateDnsToken()`API key, **Pro tier or above**`string``DomainVerification::verifyDnsToken()`API key, **Pro tier or above**`?string``DomainVerification::sendEmail()`API key, **Pro tier or above**`void`### Installation

[](#installation)

To install this package via [Composer](https://getcomposer.org/):

```
composer require elliotjreed/haveibeenpwned
```

### Count of breaches by email address

[](#count-of-breaches-by-email-address)

*Requires an API key (Core tier or above).*

Return a count of all breaches for a specified email address (`int`).

```
$guzzle = new \GuzzleHttp\Client();
$apiKey = 'HIBP-API-KEY';

$count = (new \ElliotJReed\HaveIBeenPwned\BreachedAccount($guzzle, $apiKey))->count('email@example.com');
```

### Breaches by email address

[](#breaches-by-email-address)

*Requires an API key (Core tier or above).*

Return details of all breaches for a specified email address (`ElliotJReed\HaveIBeenPwned\Entity\Breach[]`).

```
$guzzle = new \GuzzleHttp\Client();
$apiKey = 'HIBP-API-KEY';

$breaches = (new \ElliotJReed\HaveIBeenPwned\BreachedAccount($guzzle, $apiKey))->breaches('email@example.com');
```

### Breach names by email address

[](#breach-names-by-email-address)

*Requires an API key (Core tier or above).*

Return the names of the breaches for a specified email address (`string[]`);

```
$guzzle = new \GuzzleHttp\Client();
$apiKey = 'HIBP-API-KEY';

$breachNames = (new \ElliotJReed\HaveIBeenPwned\BreachedAccount($guzzle, $apiKey))->breachNames('email@example.com');
```

The `breaches()`, `breachNames()` and `count()` methods all accept an optional `$domain` argument to filter results to a single breached site, e.g. `breaches('email@example.com', domain: 'adobe.com')`.

### Whether an email address has been breached

[](#whether-an-email-address-has-been-breached)

*Requires an API key (Core tier or above).*

Return whether a specified email address has appeared in any breach (`bool`).

```
$guzzle = new \GuzzleHttp\Client();
$apiKey = 'HIBP-API-KEY';

$isBreached = (new \ElliotJReed\HaveIBeenPwned\BreachedAccount($guzzle, $apiKey))->isBreached('email@example.com');
```

### Breach names by email address using k-anonymity

[](#breach-names-by-email-address-using-k-anonymity)

*Requires an API key on the **Pro** tier or above - this is a Pro-only endpoint even though the plain email search above works on Core. A Core-tier key will receive a 403 Forbidden response.*

Return the names of the breaches for a specified email address (`string[]`) without sending the full email address to the API - only the first 6 characters of its SHA-1 hash are sent.

```
$guzzle = new \GuzzleHttp\Client();
$apiKey = 'HIBP-API-KEY';

$breachNames = (new \ElliotJReed\HaveIBeenPwned\BreachedAccount($guzzle, $apiKey))->breachNamesByHashRange('email@example.com');
```

### Count of exposed passwords by password

[](#count-of-exposed-passwords-by-password)

*No API key or subscription required - the Pwned Passwords API is free and public. The `$apiKey` argument may be an empty string.*

Return a count of exposed passwords for a specified password (`int`).

Note: This API call DOES NOT send the actual password to the Have I Been Pwned API, see: .

```
$guzzle = new \GuzzleHttp\Client();
$apiKey = 'HIBP-API-KEY';

$count = (new \ElliotJReed\HaveIBeenPwned\Password($guzzle, $apiKey))->count('password123');
```

Pass `ntlm: true` to search NTLM hashes instead of SHA-1, and `addPadding: true` to request [padded responses](https://haveibeenpwned.com/API/v3#PwnedPasswordsPadding):

```
$count = (new \ElliotJReed\HaveIBeenPwned\Password($guzzle, $apiKey))->count('password123', ntlm: true, addPadding: true);
```

### Whether a password has been exposed

[](#whether-a-password-has-been-exposed)

*No API key or subscription required - the Pwned Passwords API is free and public.*

Return whether a specified password has appeared in a data breach (`bool`).

```
$guzzle = new \GuzzleHttp\Client();
$apiKey = 'HIBP-API-KEY';

$isPwned = (new \ElliotJReed\HaveIBeenPwned\Password($guzzle, $apiKey))->isPwned('password123');
```

### Pastes by email address

[](#pastes-by-email-address)

*Requires an API key (Core tier or above).*

Return details of a specified email address appearing on "pastes" online (`\ElliotJReed\HaveIBeenPwned\Entity\Paste[]`).

```
$guzzle = new \GuzzleHttp\Client();
$apiKey = 'HIBP-API-KEY';

$pastes = (new \ElliotJReed\HaveIBeenPwned\PastedAccount($guzzle, $apiKey))->pastes('email@example.com');
```

### Breach sources

[](#breach-sources)

*No API key required - this endpoint is free and public.*

Return all breach sources recorded by Have I Been Pwned (`\ElliotJReed\HaveIBeenPwned\Entity\Breach[]`).

```
$guzzle = new \GuzzleHttp\Client();
$apiKey = 'HIBP-API-KEY';

$allBreaches = (new \ElliotJReed\HaveIBeenPwned\Breaches($guzzle, $apiKey))->allSources();
```

`allSources()` accepts an optional `bool` argument to filter by whether a breach is flagged as a spam list, e.g. `allSources(isSpamList: true)`.

### The most recently added breach

[](#the-most-recently-added-breach)

*No API key required - this endpoint is free and public.*

Return the most recently added breach (`?ElliotJReed\HaveIBeenPwned\Entity\Breach`).

```
$guzzle = new \GuzzleHttp\Client();
$apiKey = 'HIBP-API-KEY';

$latestBreach = (new \ElliotJReed\HaveIBeenPwned\Breaches($guzzle, $apiKey))->latest();
```

### Breach source by name

[](#breach-source-by-name)

*No API key required - this endpoint is free and public.*

Return breach details by source name (`\ElliotJReed\HaveIBeenPwned\Entity\Breach`).

```
$guzzle = new \GuzzleHttp\Client();
$apiKey = 'HIBP-API-KEY';

$breachesBySource = (new \ElliotJReed\HaveIBeenPwned\Breaches($guzzle, $apiKey))->bySourceName('Adobe');
```

### Breach source by domain

[](#breach-source-by-domain)

*No API key required - this endpoint is free and public.*

Return breach details by domain name (`\ElliotJReed\HaveIBeenPwned\Entity\Breach[]`) - a domain can appear in more than one breach.

```
$guzzle = new \GuzzleHttp\Client();
$apiKey = 'HIBP-API-KEY';

$breachesBySource = (new \ElliotJReed\HaveIBeenPwned\Breaches($guzzle, $apiKey))->byDomain('adobe.com');
```

### Data classes

[](#data-classes)

*No API key required - this endpoint is free and public.*

Return the data classes used by Have I Been Pwned (`string[]`).

```
$guzzle = new \GuzzleHttp\Client();
$apiKey = 'HIBP-API-KEY';

$haveIBeenPwnedDataClasses = (new \ElliotJReed\HaveIBeenPwned\DataClasses($guzzle, $apiKey))->all();
```

### Domain search

[](#domain-search)

*Requires an API key (Core tier or above). `BreachedDomain::search()` also requires the domain to first be verified via the [Have I Been Pwned dashboard](https://haveibeenpwned.com/Dashboard) or the domain verification APIs below - searching an unverified domain returns a 403 Forbidden response.*

Return all breached email aliases for a verified domain (`array` mapping each alias to the breach names it appeared in).

```
$guzzle = new \GuzzleHttp\Client();
$apiKey = 'HIBP-API-KEY';

$breachedAddresses = (new \ElliotJReed\HaveIBeenPwned\BreachedDomain($guzzle, $apiKey))->search('example.com');
```

Return all domains added to the domain search dashboard (`\ElliotJReed\HaveIBeenPwned\Entity\SubscribedDomain[]`).

```
$guzzle = new \GuzzleHttp\Client();
$apiKey = 'HIBP-API-KEY';

$subscribedDomains = (new \ElliotJReed\HaveIBeenPwned\SubscribedDomains($guzzle, $apiKey))->all();
```

### Domain verification

[](#domain-verification)

*Requires an API key on the **Pro** tier or above.*

Generate a DNS TXT record value to verify ownership of a domain (`string`), then verify it once the record has been set (`?string`, containing a failure reason, or `null` on success), or send a verification email instead.

```
$guzzle = new \GuzzleHttp\Client();
$apiKey = 'HIBP-API-KEY';

$domainVerification = new \ElliotJReed\HaveIBeenPwned\DomainVerification($guzzle, $apiKey);

$txtRecordValue = $domainVerification->generateDnsToken('example.com');
$failureReason = $domainVerification->verifyDnsToken('example.com');

$domainVerification->sendEmail('example.com', 'admin');
```

### Stealer logs

[](#stealer-logs)

*Requires an API key on the **Pro** tier or above, regardless of domain size. Stealer log searches also require the relevant domain to first be verified via the [Have I Been Pwned dashboard](https://haveibeenpwned.com/Dashboard) - searching an unverified domain returns a 403 Forbidden response.*

```
$guzzle = new \GuzzleHttp\Client();
$apiKey = 'HIBP-API-KEY';

$stealerLog = new \ElliotJReed\HaveIBeenPwned\StealerLog($guzzle, $apiKey);

$websiteDomains = $stealerLog->byEmail('jane@example.com');
$emailAddresses = $stealerLog->byWebsiteDomain('netflix.com');
$emailAliases = $stealerLog->byEmailDomain('example.com');
```

### Subscription status

[](#subscription-status)

*Requires an API key (Core tier or above).*

Return details of the current API key's subscription (`\ElliotJReed\HaveIBeenPwned\Entity\SubscriptionStatus`).

```
$guzzle = new \GuzzleHttp\Client();
$apiKey = 'HIBP-API-KEY';

$subscriptionStatus = (new \ElliotJReed\HaveIBeenPwned\Subscription($guzzle, $apiKey))->status();
```

Development
-----------

[](#development)

PHP 7.4 or 8.0 and Composer is expected to be installed.

### Installing Composer

[](#installing-composer)

For instructions on how to install Composer visit [getcomposer.org](https://getcomposer.org/download/).

### Installing

[](#installing)

After cloning this repository, change into the newly created directory and run:

```
composer install
```

or if you have installed Composer locally in your current directory:

```
php composer.phar install
```

This will install all dependencies needed for the project.

Henceforth, the rest of this README will assume `composer` is installed globally (ie. if you are using `composer.phar` you will need to use `composer.phar` instead of `composer` in your terminal / command-line).

Running the Tests
-----------------

[](#running-the-tests)

### Unit tests

[](#unit-tests)

Unit testing in this project is via [PHPUnit](https://phpunit.de/).

All unit tests can be run by executing:

```
composer phpunit
```

#### Debugging

[](#debugging)

To have PHPUnit stop and report on the first failing test encountered, run:

```
composer phpunit:debug
```

### Static analysis

[](#static-analysis)

Static analysis tools can point to potential "weak spots" in your code, and can be useful in identifying unexpected side-effects.

[Psalm](https://psalm.dev/) is configured at it's highest levels, meaning false positives are quite likely.

All static analysis tests can be run by executing:

```
composer static-analysis
```

Code formatting
---------------

[](#code-formatting)

A standard for code style can be important when working in teams, as it means that less time is spent by developers processing what they are reading (as everything will be consistent).

Code format checking (via [PHP Code Sniffer](https://github.com/PHPCSStandards/PHP_CodeSniffer)) can be run by executing:

```
composer phpcs
```

### Running everything

[](#running-everything)

All of the tests can be run by executing:

```
composer test
```

### Outdated dependencies

[](#outdated-dependencies)

Checking for outdated Composer dependencies can be performed by executing:

```
composer outdated
```

### Validating Composer configuration

[](#validating-composer-configuration)

Checking that the [composer.json](composer.json) is valid can be performed by executing:

```
composer validate --no-check-publish
```

### Running via GNU Make

[](#running-via-gnu-make)

If GNU [Make](https://www.gnu.org/software/make/) is installed, you can replace the above `composer` command prefixes with `make`.

All of the tests can be run by executing:

```
make test
```

### Running the tests on a Continuous Integration platform (eg. Travis)

[](#running-the-tests-on-a-continuous-integration-platform-eg-travis)

To run all the tests and report code coverage in Clover XML format (which many CI platforms can read, including Travis CI), add the following to your CI config (eg. [.travis.yml](.travis.yml)):

```
  script:
    - composer ci
```

Coding standards
----------------

[](#coding-standards)

PHP coding standards are quite strict and are defined in [ruleset.xml](ruleset.xml).

The rules are PSR-2 and PSR-12 standards with additionally defined rules.

The code formatting checks can be run by executing:

```
composer phpcs
```

To automatically fix any issues where possible, run:

```
composer phpcs:fix
```

Built With
----------

[](#built-with)

- [PHP](https://secure.php.net/)
- [Composer](https://getcomposer.org/)
- [PHPUnit](https://phpunit.de/)
- [Psalm](https://psalm.dev/)
- [PHP Code Sniffer](https://github.com/PHPCSStandards/PHP_CodeSniffer)
- [GNU Make](https://www.gnu.org/software/make/)

License
-------

[](#license)

This project is licensed under the MIT License - see the [LICENCE.md](LICENCE.md) file for details.

###  Health Score

60

—

FairBetter than 98% of packages

Maintenance96

Actively maintained with recent releases

Popularity36

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity77

Established project with proven stability

 Bus Factor1

Top contributor holds 97.6% 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 ~240 days

Recently: every ~320 days

Total

9

Last Release

26d ago

Major Versions

1.2.0 → 2.0.02023-12-16

2.0.0 → 3.0.02024-12-15

3.0.0 → 4.0.02026-07-24

PHP version history (4 changes)1.0.3PHP ^7.4|^8.0

2.0.0PHP ^8.1

3.0.0PHP ^8.2

4.0.0PHP ^8.4

### Community

Maintainers

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

---

Top Contributors

[![elliotjreed](https://avatars.githubusercontent.com/u/5665859?v=4)](https://github.com/elliotjreed "elliotjreed (40 commits)")[![rodrigoprimo](https://avatars.githubusercontent.com/u/77215?v=4)](https://github.com/rodrigoprimo "rodrigoprimo (1 commits)")

---

Tags

composerhacktoberfesthaveibeenpwnedpassword-safetypassword-strengthphphaveibeenpwnedelliotjreed

###  Code Quality

TestsPHPUnit

Code StylePHP CS Fixer

### Embed Badge

![Health badge](/badges/elliotjreed-haveibeenpwned/health.svg)

```
[![Health](https://phpackages.com/badges/elliotjreed-haveibeenpwned/health.svg)](https://phpackages.com/packages/elliotjreed-haveibeenpwned)
```

###  Alternatives

[aws/aws-sdk-php

AWS SDK for PHP - Use Amazon Web Services in your PHP project

6.2k555.0M2.8k](/packages/aws-aws-sdk-php)[neuron-core/neuron-ai

The PHP Agentic Framework.

2.0k832.6k55](/packages/neuron-core-neuron-ai)[tencentcloud/tencentcloud-sdk-php

TencentCloudApi php sdk

3661.3M49](/packages/tencentcloud-tencentcloud-sdk-php)[eslazarev/wildberries-sdk

Wildberries OpenAPI clients (generated).

353.6k](/packages/eslazarev-wildberries-sdk)[tempest/framework

The PHP framework that gets out of your way.

2.3k37.6k21](/packages/tempest-framework)[files.com/files-php-sdk

Files.com PHP SDK

2482.9k](/packages/filescom-files-php-sdk)

PHPackages © 2026

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