API Documentation

The API allows the list of pwned accounts (email addresses, usernames and phone numbers) to be quickly searched via a RESTful service

Index

You're reading about v3 of the API which is presently the current version and contains breaking changes over previous versions for searching breaches and pastes via email address.

Overview

Authorisation

Authorisation is required for all APIs that enable searching HIBP by email address or domain, namely retrieving all breaches for an account, retrieving all pastes for an account, retrieving all breached email addresses for a domain and retrieving all stealer log domains for a breached email addresses. There is no authorisation required for the free Pwned Passwords API. An HIBP subscription key is required to make an authorised call and can be obtained on the API key page. The key is then passed in a "hibp-api-key" header:

GET https://haveibeenpwned.com/api/v3/{service}/{parameter} hibp-api-key: [your key]

Semantic HTTP response codes are used to indicate the result of the API call:

Code Description
401 Unauthorised — the API key provided was not valid

Additional information may be present in the response body when an API call fails, for example:

Access denied due to missing hibp-api-key.
Access denied due to improperly formed hibp-api-key.
Access denied due to invalid hibp-api-key.

HIBP API keys must be 32-character hexadecimal strings. Keys undergo an initial format check, followed by validation to confirm their authenticity before any processing occurs.

Test API Key

Where supported, a test API key can be used instead of a paid subscription. Test keys provide limited access (typically to test accounts) and may be any value that conforms to the required key format. For example:

GET https://haveibeenpwned.com/api/v3/{service}/{parameter} hibp-api-key: 00000000000000000000000000000000

Specifying the API version

Version 3 of the API is consumable only by specifying the API version in the URL. All API endpoints are requested with the following pattern:

GET https://haveibeenpwned.com/api/v3/{service}/{parameter}

Specifying the user agent

Each request to the API must be accompanied by a user agent request header. Typically this should be the name of the app consuming the service. A missing user agent will result in an HTTP 403 response. A valid request would look like:

GET https://haveibeenpwned.com/api/v3/{service}/{parameter} user-agent: [your app name]

The user agent should accurately describe the nature of the API consumer such that it can be clearly identified in the request. Not doing so may result in the request being blocked.

Breaches

Getting all breaches for an account

The most common use of the API is to return a list of all breaches a particular account has been involved in. The API takes a single parameter which is the account to be searched for. The account is not case-sensitive and will be trimmed of leading or trailing white spaces. The account should always be URL encoded. This is an authenticated API and an HIBP API key must be passed with the request.

GET https://haveibeenpwned.com/api/v3/breachedaccount/{account} hibp-api-key: [your key]

If the account is found in a breach, an HTTP 200 response is returned. By default, only the name of the breach is returned rather than the complete breach data, thus reducing the response body size by approximately 98% compared to returning the full breach model.

[ { "Name": "Adobe" }, { "Name": "Gawker" }, { "Name": "Stratfor" } ]

The name can then be used to either retrieve a single breach or it can be found in the list of all breaches in the system. If you'd like complete breach data returned in the API call, a non-truncated response can be specified via query string parameter:

Parameter Example Description
truncateResponse ?truncateResponse=false Returns the full breach model.

Note: the public API will not return accounts from any breaches flagged as sensitive or retired. By default, the API will return breaches flagged as unverified, however these can be excluded by using the following parameter:

Parameter Example Description
IncludeUnverified ?IncludeUnverified=false Returns breaches that have been flagged as "unverified". By default, both verified and unverified breaches are returned when performing a search.

If the account is not found in a breach, an HTTP 404 response will be returned. See the response codes section of the API docs for more information, including other response codes that me be returned.

Getting all breached email addresses for a domain

All email addresses on a given domain and the breaches they've appeared in can be returned via the domain search API. Only domains that have been successfully added to the domain search dashboard after verifying control can be searched. The API takes a single parameter which is the domain to be searched for and is an authenticated API requiring an HIBP API key.

GET https://haveibeenpwned.com/api/v3/breacheddomain/{domain} hibp-api-key: [your key]

If one or more results are found, an HTTP 200 response is returned. For each breached email address on the domain, only the alias is returned along with each breach it has appeared in. Only the name attribute of the breach is returned which can then be used to retrieve a single breach or it can be found in the list of all breaches in the system.

{ "alias1": ["Adobe"], "alias2": ["Adobe", "Gawker", "Stratfor"], "alias3": ["AshleyMadison"] }

In the above example, if the domain searched for is example.com then 3 email addresses have been found:

  • alias1@example.com is in the Adobe data breach
  • alias2@example.com is in the Adobe, Gawker and Stratfor data breaches
  • alias3@example.com is in the Ashley Madison data breach

If the domain does not have any email addresses in any breaches, an HTTP 404 response will be returned. See the response codes section of the API docs for more information, including other response codes that me be returned.

Note: the domain search API will return sensitive data breaches as it can only be called after demonstrating control of the domain.

Getting all subscribed domains

Domains that have been successfully added to the domain search dashboard after verifying control are returned via this API. This is an authenticated API requiring an HIBP API key which will then return all domains associated with that key.

GET https://haveibeenpwned.com/api/v3/subscribeddomains

Getting all breached sites in the system

A "breach" is an instance of a system having been compromised by an attacker and the data disclosed. For example, Adobe was a breach, Gawker was a breach etc. It is possible to return the details of each of breach in the system which currently stands at 920 breaches.

GET https://haveibeenpwned.com/api/v3/breaches

The result set can also be filtered by passing one of the following query strings:

Parameter Example Description
Domain ?Domain=adobe.com Filters the result set to only breaches against the domain specified. It is possible that one site (and consequently domain), is compromised on multiple occasions.
IsSpamList ?IsSpamList=true Filters the result set to only breaches that either are or are not flagged as a spam list.

Getting a single breached site by name

Sometimes just a single breach is required and this can be retrieved by the breach "Name". This is the stable value which may or may not be the same as the breach "Title", which can change. See the breach model below for more info.

GET https://haveibeenpwned.com/api/v3/breach/{name}

Getting the most recently added breach

Often, it's most efficient to monitor for new breaches before performing other actions, for example querying an account or domain. Issuing queries over and over again when no new breaches have been loaded since the last query is usually sub-optimal. This API returns the most recently added breach based on the "AddedDate" attribute of the breach model. This may not be the most recent breach to occur as there may be significant lead time between a service being breached and the data later appearing on HIBP. See the breach model below for more info.

GET https://haveibeenpwned.com/api/v3/latestbreach

Getting all data classes

A "data class" is an attribute of a record compromised in a breach. For example, many breaches expose data classes such as "Email addresses" and "Passwords". The values returned by this service are ordered alphabetically in a string array and will expand over time as new breaches expose previously unseen classes of data.

GET https://haveibeenpwned.com/api/v3/dataclasses

The breach model

Each breach contains a number of attributes describing the incident. In the future, these attributes may expand without the API being versioned. The current attributes are:

Attribute Type Description
Name string A Pascal-cased name representing the breach which is unique across all other breaches. This value never changes and may be used to name dependent assets (such as images) but should not be shown directly to end users (see the "Title" attribute instead).
Title string A descriptive title for the breach suitable for displaying to end users. It's unique across all breaches but individual values may change in the future (i.e. if another breach occurs against an organisation already in the system). If a stable value is required to reference the breach, refer to the "Name" attribute instead.
Domain string The domain of the primary website the breach occurred on. This may be used for identifying other assets external systems may have for the site.
BreachDate string The date (with no time) the breach originally occurred on in ISO 8601 format. This is not always known and may be null.
AddedDate datetime The date and time (precision to the minute) the breach was added to the system in ISO 8601 format.
ModifiedDate datetime The date and time (precision to the minute) the breach was modified in ISO 8601 format. This will be equal to AddedDate for new breaches, then should increase whenever any breach attributes are changed.
PwnCount integer The total number of accounts loaded in the breach. This is usually less than the total number of accounts in a breach as many sites do not publicly report the total count.
Description string Contains an overview of the breach compiled by HIBP in HTML format. The description may include markup such as emphasis and strong tags as well as hyperlinks.
DataClasses array This attribute describes the nature of the data compromised in the breach and contains an alphabetically ordered string array of impacted data classes.
IsVerified boolean Indicates that the breach is considered "verified". An unverified breach may not have been hacked from the indicated service.
IsFabricated boolean Indicates that the breach is considered "fabricated" — a fake breach created by a troll or spammer to contain inaccurate data.
IsSensitive boolean Indicates if the breach is considered "sensitive". The public API will not return any accounts from a breach flagged as sensitive.
IsRetired boolean Indicates if the breach has been "retired". This data has been permanently removed and will not be returned by the API.
IsSpamList boolean Indicates if the breach is considered a "spam list". This flag has no impact on any other attributes but it means that the data has not come as a result of a security compromise.
IsMalware boolean Indicates if the breach is considered "malware". This flag has no impact on any other attributes.
IsStealerLog boolean Indicates if the breach is considered a "stealer log". This flag has no impact on any other attributes.
IsSubscriptionFree boolean Indicates if the breach is considered "subscription-free". This flag has no impact on any other attributes.

Sample breach response

{ "Name": "Adobe", "Title": "Adobe", "Domain": "adobe.com", "BreachDate": "2013-10-04", "AddedDate": "2013-12-04T00:00:00Z", "ModifiedDate": "2022-05-15T23:52:49Z", "PwnCount": 152445165, "Description": "In October 2013, 153 million Adobe accounts were breached...", "DataClasses": ["Email addresses", "Password hints", "Passwords", "Usernames"], "IsVerified": true, "IsFabricated": false, "IsSensitive": false, "IsRetired": false, "IsSpamList": false, "IsMalware": false, "IsStealerLog": false, "IsSubscriptionFree": false }

Stealer logs

Overview

Stealer logs are collections of credentials stolen by information-stealing malware. When such malware infects a device, it extracts data from browsers and other applications then uploads it to attacker-controlled infrastructure. These logs are then aggregated and sold or shared within cybercriminal communities.

Getting all stealer log domains for an email address

This API returns all domains that have appeared in stealer logs for a given email address. This is an authenticated API requiring an HIBP API key.

GET https://haveibeenpwned.com/api/v3/stealerlogdomains/{email} hibp-api-key: [your key]

Getting all stealer log email addresses for a website domain

This API returns all email addresses from a verified domain that have appeared in stealer logs. Only domains that have been successfully added to the domain search dashboard after verifying control can be searched. This is an authenticated API requiring an HIBP API key.

GET https://haveibeenpwned.com/api/v3/stealerlogdomain/{domain} hibp-api-key: [your key]

Getting all stealer log email aliases for an email domain

This API returns all email aliases from a verified domain that have appeared in stealer logs. Only domains that have been successfully added to the domain search dashboard after verifying control can be searched. This is an authenticated API requiring an HIBP API key.

GET https://haveibeenpwned.com/api/v3/stealerlogemaildomain/{domain} hibp-api-key: [your key]

Pastes

Getting all pastes for an account

Pastebin (and similar sites) are used by attackers to share data. This API allows you to search for a particular account and get all pastes that account has been found in. The account is not case-sensitive and will be trimmed of leading or trailing white spaces. The account should always be URL encoded. This is an authenticated API and an HIBP API key must be passed with the request.

GET https://haveibeenpwned.com/api/v3/pasteaccount/{account} hibp-api-key: [your key]

If the account is found in any pastes, an HTTP 200 response is returned with an array of paste objects. If the account is not found in any pastes, an HTTP 404 response will be returned.

The paste model

Each paste contains a number of attributes describing the incident:

Attribute Type Description
Source string The paste service the record was retrieved from. Current values are: Pastebin, Pastie, Slexy, Ghostbin, QuickLeak, JustPaste, AdHocUrl, OptOut
Id string The ID of the paste as it was given by the source service. Combined with the "Source" attribute, this can be used to resolve the URL of the paste.
Title string The title of the paste as observed on the source site. This may be null.
Date datetime The date and time (precision to the second) that the paste was posted. This is taken directly from the paste site when this information is available but may be null if no date is published.
EmailCount integer The number of email addresses found in the paste. This will be null if no email addresses were found or the paste is not available.

Sample paste response

[ { "Source": "Pastebin", "Id": "8Q0BvKD8", "Title": "syslog", "Date": "2014-03-04T19:15:45Z", "EmailCount": 137 } ]

Subscription

Getting the subscription status

This API returns the subscription status for the provided API key. This is an authenticated API requiring an HIBP API key.

GET https://haveibeenpwned.com/api/v3/subscriptionstatus hibp-api-key: [your key]

Pwned Passwords

Overview

The Pwned Passwords API is completely free to use and allows you to check if a password has been found in any of the data breaches loaded into Have I Been Pwned. The API uses a k-anonymity model that allows a password to be searched for by partial hash. This allows the first 5 characters of a SHA-1 password hash (not the password itself) to be passed to the API.

Searching by a range

When a password hash with the same first 5 characters is found in the Pwned Passwords repository, the API will respond with an HTTP 200 and include the suffix of every hash beginning with the specified prefix, followed by a count of how many times it appears in the data set. The API consumer can then search the results for their full hash.

GET https://api.pwnedpasswords.com/range/{first5CharsHash}

Introducing padding

To prevent timing attacks, the API supports padding via the "Add-Padding" response header. When this header is set to "true", the API will add fake results to the response to make it appear as if the hash prefix was found, even when it wasn't.

Incremental searches

For applications that need to check multiple passwords, the API supports incremental searching where you can check multiple hash prefixes in a single request.

Searching for NTLM hashes

The API also supports searching for NTLM hashes using the same k-anonymity model.

GET https://api.pwnedpasswords.com/range/{first5CharsNTLMHash}?mode=ntlm

Downloading all Pwned Passwords hashes

The complete list of Pwned Passwords hashes can be downloaded for offline use. The download is available as a torrent or direct download.

Further reading

HTTPS

All API endpoints are only available over HTTPS. Any HTTP requests will receive a 301 redirect to the HTTPS equivalent.

Response codes

Semantic HTTP response codes are used to indicate the result of the API call:

Code Description
200 OK — everything worked and there's a string array of pwned sites for the account
400 Bad request — the account does not comply with an acceptable format (i.e. it's an empty string)
401 Unauthorised — the API key provided was not valid
403 Forbidden — no user agent has been specified in the request
404 Not found — the account could not be found and has therefore not been pwned
429 Too many requests — the rate limit has been exceeded
503 Service unavailable — usually returned by Cloudflare if the service is under heavy load or there are other availability issues

Test accounts

For testing purposes, there are several test accounts available on the hibp-integration-tests.com domain. These can be used with test API keys to verify your integration without requiring a paid subscription.

Cross-origin resource sharing (CORS)

CORS is only supported for non-authenticated APIs. APIs requiring a key should not be hit directly from the client side as it exposes the secret to other users. Instead, proxy the request through your own API and handle the authorisation between there and the client in your own code.

On supported APIs, CORS accepts all origins — you can hit the API from websites on any other domain.

Rate limiting

Requests to the breaches, pastes and stealer log APIs are rate limited. The rate limits depends on the the API key you've purchased. Any request that exceeds the limit will receive an HTTP 429 "Too many requests" response. The response also includes an accompanying "retry-after" response header expressing the number of seconds remaining before the client can make a successful API call with the same key (the value is rounded up to the next whole second). The response body explains the rate limit and refers to the acceptable use documentation.

HTTP/1.1 429 retry-after: 2 { "statusCode": 429, "message": "Rate limit is exceeded. Try again in 2 seconds." }

It's advisable to avoid querying the API at exactly the rate limit as network behaviour may result in some requests arriving within the retry period and causing a 429. Adding a short delay between requests on top of the rate limit will usually ensure this won't happen.

There is no official rate limit for the domain search API, although the intention is to query it infrequently, usually only after a new breach is loaded. Regular querying of the domain search API beyond what is practically necessary may result in measures being applied to reduce the query rate and respond with an HTTP 429.

Where the rate limit is consistently exceeded, further defences may be employed to limit the ability to query the API. These defences include blocks or JavaScript challenges by Cloudflare which may result in an HTTP 503 "Service Unavailable" response.

There is no rate limit on the Pwned Passwords API.

Abuse

There's not much point; if you want to build up a treasure trove of pwned email addresses or usernames, go and download the dumps (they're usually just a Google search away) and save yourself the hassle and time of trying to enumerate an API one account at a time. That said, use of the API should fall within acceptable use expectations:

Acceptable use

The API has been designed to make it easy for people to do awesome things with it. Things that are not awesome include:

  • Querying the data for purposes that are intended to cause harm to the victims of data breaches
  • Anything deliberately intended to limit service availability such as denial of service attacks
  • Deliberate attempts to circumvent measures designed to ensure acceptable use
  • Not properly identifying the user agent such that it accurately describes the consumer of the API
  • Misrepresenting the consuming client by impersonating other user agents in an attempt to obfuscate API requests
  • Other services designed to fraudulently represent the Have I Been Pwned name or brand
  • Misrepresenting the source of the data as originating from somewhere other than Have I Been Pwned
  • Not adhering to the Creative Commons Attribution License as described below
  • Automating the consumption of other APIs not explicitly documented on this page
  • Using the service in a fashion that brings Have I Been Pwned into disrepute

Abusing these objectives may limit your ability to query the service via a range of countermeasures. Those countermeasures may impact other consumers of the API if they share network services with an abusive user. If in doubt, get in touch and outline how you'd like to use the service in a way that's consistent with these objectives.

License — breach & paste APIs

This work is licensed under a Creative Commons Attribution 4.0 International License.

In other words, you're welcome to use the public API to build other services, but you must identify Have I Been Pwned as the source of the data. Clear and visible attribution with a link to haveibeenpwned.com should be present anywhere data from the service is used including when searching breaches or pastes and when representing breach descriptions. It doesn't have to be overt, but the interface in which Have I Been Pwned data is represented should clearly attribute the source per the Creative Commons Attribution 4.0 International License.

In order to help maximise adoption, there is no licencing or attribution requirements on the Pwned Passwords API, although it is welcomed if you would like to include it.