Breaches
Browse the public breach catalogue or look up the breaches tied to a specific account. Account searches are authenticated; the catalogue endpoints are open.
IPwnedBreachesClientBreach catalogue lookups plus account exposure searches, including the privacy-preserving k-anonymity variant.
Inject IPwnedBreachesClient for breach work, or the aggregate IPwnedClient when you need every surface. Both resolve to the same singleton.
using HaveIBeenPwned.Client;
var builder = WebApplication.CreateBuilder(args);
// Binds the "HibpOptions" section from appsettings.json.
builder.Services.AddPwnedServices(
builder.Configuration.GetSection(nameof(HibpOptions)));
var app = builder.Build();GetBreachesForAccountAsyncAPI key
Returns the full breach details for every breach an account has appeared in. This is the untruncated search, so each result carries the complete BreachDetails payload.
GEThaveibeenpwned.com/api/v3/breachedaccount/{account}?truncateResponse=false&includeUnverified={includeUnverified}&domain={domain}Request detailsHide details
GET /api/v3/breachedaccount/{account}?truncateResponse=false&includeUnverified={includeUnverified}&domain={domain} HTTP/1.1Host: haveibeenpwned.comAccept: application/jsonhibp-api-key: ••••••••••••The SDK reads the configured key and adds the hibp-api-key header for this request.
The SDK deserializes the response into the documented .NET return type.
Task<BreachDetails[]> GetBreachesForAccountAsync(
string account,
bool includeUnverified = true,
string? domain = null,
CancellationToken ct = default)| Name | Type | Description |
|---|---|---|
accountrequired | string | Email address or username to search. Trimmed and URL encoded for you. |
includeUnverified | bool | Include unverified breaches. Defaults to true. |
domain | string? | Restrict results to a single breach domain. |
ct | CancellationToken | Signals cancellation. |
Task<BreachDetails[]> | Full breach records, or an empty array when the account is clean (HTTP 404). |
| Streams | Also available as GetBreachesForAccountAsAsyncEnumerable for IAsyncEnumerable consumption. |
public sealed class ExposureReport(IPwnedBreachesClient breaches)
{
public async Task PrintAsync(string account)
{
BreachDetails[] results =
await breaches.GetBreachesForAccountAsync(account);
foreach (var breach in results)
{
Console.WriteLine(
$"{breach.Title} ({breach.BreachDate:yyyy-MM-dd}) " +
$"exposed {breach.PwnCount:N0} accounts.");
}
}
}Running the snippet above prints:
Adobe (2013-10-04) exposed 152,445,165 accounts.
LinkedIn (2012-05-05) exposed 164,611,595 accounts.| Type | Thrown when |
|---|---|
ArgumentNullException | account is null, empty, or whitespace. |
PwnedApiException | Any non-success status other than 404 (which maps to an empty array). |
| Code | Meaning |
|---|---|
| 200 | Breaches found for the account. |
| 401 | Missing or invalid API key. |
| 404 | No breaches for the account. Returned to you as an empty array. |
| 429 | Rate limit exceeded. The Retry-After header is surfaced on PwnedApiException.RetryAfter. |
| 503 | Service temporarily unavailable. Retried by the resilience pipeline when configured. |
Account searches require an API key set on HibpOptions.ApiKey.
Prefer the k-anonymity variant when you do not need full breach detail and want to avoid sending the full address.
GetBreachHeadersForAccountAsyncAPI key
The truncated account search. Returns only breach names, which is the lightest way to answer "has this account been in a breach?".
GEThaveibeenpwned.com/api/v3/breachedaccount/{account}?truncateResponse=true&includeUnverified={includeUnverified}&domain={domain}Request detailsHide details
GET /api/v3/breachedaccount/{account}?truncateResponse=true&includeUnverified={includeUnverified}&domain={domain} HTTP/1.1Host: haveibeenpwned.comAccept: application/jsonhibp-api-key: ••••••••••••The SDK reads the configured key and adds the hibp-api-key header for this request.
The SDK deserializes the response into the documented .NET return type.
Task<BreachHeader[]> GetBreachHeadersForAccountAsync(
string account,
bool includeUnverified,
string? domain = null,
CancellationToken ct = default)| Name | Type | Description |
|---|---|---|
accountrequired | string | Email address or username to search. |
includeUnverified | bool | Include unverified breaches. |
domain | string? | Restrict results to a single breach domain. |
ct | CancellationToken | Signals cancellation. |
Task<BreachHeader[]> | Breach headers (Name only), or an empty array when the account is clean. |
| Streams | Also available as GetBreachHeadersForAccountAsAsyncEnumerable for IAsyncEnumerable consumption. |
BreachHeader[] headers =
await breaches.GetBreachHeadersForAccountAsync(
"account@example.com",
includeUnverified: false);
Console.WriteLine($"{headers.Length} breaches on record.");Running the snippet above prints:
3 breaches on record.| Type | Thrown when |
|---|---|
ArgumentNullException | account is null, empty, or whitespace. |
PwnedApiException | Any non-success status other than 404. |
| Code | Meaning |
|---|---|
| 200 | Breach headers found. |
| 401 | Missing or invalid API key. |
| 404 | No breaches. Returned as an empty array. |
| 429 | Rate limit exceeded. The Retry-After header is surfaced on PwnedApiException.RetryAfter. |
| 503 | Service temporarily unavailable. Retried by the resilience pipeline when configured. |
GetBreachHeadersForAccountUsingKAnonymityAsyncAPI key
Searches breaches by sending only the first six characters of the SHA-1 hash of the normalized address. The client filters the returned range locally so the full address never leaves your process.
GEThaveibeenpwned.com/api/v3/breachedaccount/range/{hashPrefix}Request detailsHide details
GET /api/v3/breachedaccount/range/{hashPrefix} HTTP/1.1Host: haveibeenpwned.comAccept: application/jsonhibp-api-key: ••••••••••••The SDK reads the configured key and adds the hibp-api-key header for this request.
The SDK deserializes the response into the documented .NET return type.
Task<BreachHeader[]> GetBreachHeadersForAccountUsingKAnonymityAsync(
string account,
CancellationToken ct = default)| Name | Type | Description |
|---|---|---|
accountrequired | string | Email address to search. Only a six-character hash prefix is sent. |
ct | CancellationToken | Signals cancellation. |
Task<BreachHeader[]> | Locally matched breach headers, or an empty array. |
| Streams | Also available as GetBreachHeadersForAccountUsingKAnonymityAsAsyncEnumerable for IAsyncEnumerable consumption. |
BreachHeader[] headers =
await breaches.GetBreachHeadersForAccountUsingKAnonymityAsync(
"account@example.com");
foreach (var header in headers)
{
Console.WriteLine(header.Name);
}Running the snippet above prints:
Adobe
LinkedIn
Dropbox| Type | Thrown when |
|---|---|
ArgumentNullException | account is null, empty, or whitespace. |
PwnedApiException | Any non-success status while fetching the hash range. |
| Code | Meaning |
|---|---|
| 200 | Hash range returned and filtered locally. |
| 401 | Missing or invalid API key. |
| 429 | Rate limit exceeded. The Retry-After header is surfaced on PwnedApiException.RetryAfter. |
| 503 | Service temporarily unavailable. Retried by the resilience pipeline when configured. |
Matching happens on your machine, so range entries that do not match the requested address must never be retained.
GetBreachesAsyncNone
Lists breach headers from the public catalogue, with optional domain and spam-list filters. No API key required.
GEThaveibeenpwned.com/api/v3/breaches?domain={domain}&isSpamList={isSpamList}Request detailsHide details
GET /api/v3/breaches?domain={domain}&isSpamList={isSpamList} HTTP/1.1Host: haveibeenpwned.comAccept: application/jsonThis public endpoint is called without an API key or authorization header.
The SDK deserializes the response into the documented .NET return type.
Task<BreachHeader[]> GetBreachesAsync(
string? domain = default,
bool? isSpamList = null,
CancellationToken ct = default)| Name | Type | Description |
|---|---|---|
domain | string? | Filter to breaches for a single domain. |
isSpamList | bool? | Filter to breaches that are, or are not, spam lists. |
ct | CancellationToken | Signals cancellation. |
Task<BreachHeader[]> | Breach headers for the whole catalogue, or an empty array. |
| Streams | Also available as GetBreachesAsAsyncEnumerable for IAsyncEnumerable consumption. |
BreachHeader[] all = await breaches.GetBreachesAsync();
Console.WriteLine($"{all.Length} breaches in the catalogue.");Running the snippet above prints:
857 breaches in the catalogue.| Type | Thrown when |
|---|---|
PwnedApiException | Any non-success status. |
| Code | Meaning |
|---|---|
| 200 | Catalogue returned. |
| 429 | Rate limit exceeded. The Retry-After header is surfaced on PwnedApiException.RetryAfter. |
| 503 | Service temporarily unavailable. Retried by the resilience pipeline when configured. |
GetAllBreachDetailsAsyncNone
Like GetBreachesAsync, but returns the full BreachDetails for every breach. Useful for building a local mirror of the catalogue.
GEThaveibeenpwned.com/api/v3/breaches?domain={domain}&isSpamList={isSpamList}Request detailsHide details
GET /api/v3/breaches?domain={domain}&isSpamList={isSpamList} HTTP/1.1Host: haveibeenpwned.comAccept: application/jsonThis public endpoint is called without an API key or authorization header.
The SDK deserializes the response into the documented .NET return type.
Task<BreachDetails[]> GetAllBreachDetailsAsync(
string? domain = default,
bool? isSpamList = null,
CancellationToken ct = default)| Name | Type | Description |
|---|---|---|
domain | string? | Filter to breaches for a single domain. |
isSpamList | bool? | Filter on the spam-list flag. |
ct | CancellationToken | Signals cancellation. |
Task<BreachDetails[]> | Full breach details for the catalogue, or an empty array. |
| Streams | Also available as GetAllBreachDetailsAsAsyncEnumerable for IAsyncEnumerable consumption. |
BreachDetails[] details =
await breaches.GetAllBreachDetailsAsync(isSpamList: false);
var largest = details.MaxBy(static b => b.PwnCount);
Console.WriteLine($"Largest: {largest?.Title} ({largest?.PwnCount:N0}).");Running the snippet above prints:
Largest: Collection #1 (772,904,991).| Type | Thrown when |
|---|---|
PwnedApiException | Any non-success status. |
| Code | Meaning |
|---|---|
| 200 | Catalogue returned. |
| 429 | Rate limit exceeded. The Retry-After header is surfaced on PwnedApiException.RetryAfter. |
| 503 | Service temporarily unavailable. Retried by the resilience pipeline when configured. |
GetBreachAsyncNone
Fetches a single breach by its stable Name. Returns null when no breach matches.
GEThaveibeenpwned.com/api/v3/breach/{breachName}Request detailsHide details
GET /api/v3/breach/{breachName} HTTP/1.1Host: haveibeenpwned.comAccept: application/jsonThis public endpoint is called without an API key or authorization header.
The SDK deserializes the response into the documented .NET return type.
Task<BreachDetails?> GetBreachAsync(
string breachName,
CancellationToken ct = default)| Name | Type | Description |
|---|---|---|
breachNamerequired | string | The stable breach name, for example "Adobe". |
ct | CancellationToken | Signals cancellation. |
Task<BreachDetails?> | The breach record, or null when the name is unknown (HTTP 404). |
BreachDetails? adobe = await breaches.GetBreachAsync("Adobe");
if (adobe is not null)
{
Console.WriteLine(string.Join(", ", adobe.DataClasses));
}Running the snippet above prints:
Email addresses, Password hints, Passwords, Usernames| Type | Thrown when |
|---|---|
ArgumentNullException | breachName is null, empty, or whitespace. |
PwnedApiException | Any non-success status other than 404. |
| Code | Meaning |
|---|---|
| 200 | Breach found. |
| 404 | Unknown breach name. Returned to you as null. |
| 429 | Rate limit exceeded. The Retry-After header is surfaced on PwnedApiException.RetryAfter. |
| 503 | Service temporarily unavailable. Retried by the resilience pipeline when configured. |
GetDataClassesAsyncNone
Lists every data class the system tracks, for example "Email addresses" or "Phone numbers". Handy for building filter UIs.
GEThaveibeenpwned.com/api/v3/dataclassesRequest detailsHide details
GET /api/v3/dataclasses HTTP/1.1Host: haveibeenpwned.comAccept: application/jsonThis public endpoint is called without an API key or authorization header.
The SDK deserializes the response into the documented .NET return type.
Task<string[]> GetDataClassesAsync(CancellationToken ct = default)| Name | Type | Description |
|---|---|---|
ct | CancellationToken | Signals cancellation. |
Task<string[]> | All known data classes, or an empty array. |
| Streams | Also available as GetDataClassesAsAsyncEnumerable for IAsyncEnumerable consumption. |
string[] classes = await breaches.GetDataClassesAsync();
Console.WriteLine($"{classes.Length} data classes tracked.");Running the snippet above prints:
140 data classes tracked.| Type | Thrown when |
|---|---|
PwnedApiException | Any non-success status. |
| Code | Meaning |
|---|---|
| 200 | Data classes returned. |
| 429 | Rate limit exceeded. The Retry-After header is surfaced on PwnedApiException.RetryAfter. |
| 503 | Service temporarily unavailable. Retried by the resilience pipeline when configured. |
GetLatestBreachAsyncNone
Returns the most recently added breach, ordered by AddedDate. Returns null when the catalogue is empty.
GEThaveibeenpwned.com/api/v3/latestbreachRequest detailsHide details
GET /api/v3/latestbreach HTTP/1.1Host: haveibeenpwned.comAccept: application/jsonThis public endpoint is called without an API key or authorization header.
The SDK deserializes the response into the documented .NET return type.
Task<BreachDetails?> GetLatestBreachAsync(CancellationToken ct = default)| Name | Type | Description |
|---|---|---|
ct | CancellationToken | Signals cancellation. |
Task<BreachDetails?> | The newest breach, or null. |
BreachDetails? latest = await breaches.GetLatestBreachAsync();
Console.WriteLine($"Newest: {latest?.Title} added {latest?.AddedDate:u}.");Running the snippet above prints:
Newest: Example Forum added 2024-11-03 09:14:00Z.| Type | Thrown when |
|---|---|
PwnedApiException | Any non-success status other than 404. |
| Code | Meaning |
|---|---|
| 200 | Latest breach returned. |
| 404 | No breach available. Returned as null. |
| 429 | Rate limit exceeded. The Retry-After header is surfaced on PwnedApiException.RetryAfter. |
| 503 | Service temporarily unavailable. Retried by the resilience pipeline when configured. |
Never log or export plaintext passwords. K-anonymity range results that do not match the requested value must not be retained.