CINXE.COM

Have I Been Pwned: API v3

<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0"> <title>Have I Been Pwned: API v3</title> <meta property="og:title" content="Have I Been Pwned: API v3" /> <meta name="description" content="Have I Been Pwned allows you to search across multiple data breaches to see if your email address or phone number has been compromised."> <meta property="og:description" content="Have I Been Pwned allows you to search across multiple data breaches to see if your email address or phone number has been compromised." /> <meta property="og:url" content="https://haveibeenpwned.com/APIDocs/V3" /> <meta property="og:image" content="https://haveibeenpwned.com/Content/Images/SocialLogo.png" /> <meta property="fb:app_id" content="553845121487108" /> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha512-Dop/vW3iOtayerlYAqCgkVr2aTr2ErwwTYOvRFUpzl2VhCMJyjQF0Q9TjUXIo6JhuM/3i0vVEt2e/7QQmnHQqw==" crossorigin="anonymous" referrerpolicy="no-referrer" /> <link rel="alternate" type="application/rss+xml" title="Have I Been Pwned latest breaches" href="https://feeds.feedburner.com/HaveIBeenPwnedLatestBreaches" /> <link href="/content/css/pwned?v=QqHv4S4ISjFIUVd6yx3EVXLe_Iyc0FGEtMhu7ZZyL681" rel="stylesheet"/> <link href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous" /> <link rel="shortcut icon" href="/favicon.ico"> <script type="text/javascript" nonce="KJ8+IZ/8bM7NArC0SgLT/RkE"> !(function (cfg){function e(){cfg.onInit&&cfg.onInit(n)}var x,w,D,t,E,n,C=window,O=document,b=C.location,q="script",I="ingestionendpoint",L="disableExceptionTracking",j="ai.device.";"instrumentationKey"[x="toLowerCase"](),w="crossOrigin",D="POST",t="appInsightsSDK",E=cfg.name||"appInsights",(cfg.name||C[t])&&(C[t]=E),n=C[E]||function(g){var f=!1,m=!1,h={initialize:!0,queue:[],sv:"8",version:2,config:g};function v(e,t){var n={},i="Browser";function a(e){e=""+e;return 1===e.length?"0"+e:e}return n[j+"id"]=i[x](),n[j+"type"]=i,n["ai.operation.name"]=b&&b.pathname||"_unknown_",n["ai.internal.sdkVersion"]="javascript:snippet_"+(h.sv||h.version),{time:(i=new Date).getUTCFullYear()+"-"+a(1+i.getUTCMonth())+"-"+a(i.getUTCDate())+"T"+a(i.getUTCHours())+":"+a(i.getUTCMinutes())+":"+a(i.getUTCSeconds())+"."+(i.getUTCMilliseconds()/1e3).toFixed(3).slice(2,5)+"Z",iKey:e,name:"Microsoft.ApplicationInsights."+e.replace(/-/g,"")+"."+t,sampleRate:100,tags:n,data:{baseData:{ver:2}},ver:undefined,seq:"1",aiDataContract:undefined}}var n,i,t,a,y=-1,T=0,S=["js.monitor.azure.com","js.cdn.applicationinsights.io","js.cdn.monitor.azure.com","js0.cdn.applicationinsights.io","js0.cdn.monitor.azure.com","js2.cdn.applicationinsights.io","js2.cdn.monitor.azure.com","az416426.vo.msecnd.net"],o=g.url||cfg.src,r=function(){return s(o,null)};function s(d,t){if((n=navigator)&&(~(n=(n.userAgent||"").toLowerCase()).indexOf("msie")||~n.indexOf("trident/"))&&~d.indexOf("ai.3")&&(d=d.replace(/(\/)(ai\.3\.)([^\d]*)$/,function(e,t,n){return t+"ai.2"+n})),!1!==cfg.cr)for(var e=0;e<S.length;e++)if(0<d.indexOf(S[e])){y=e;break}var n,i=function(e){var a,t,n,i,o,r,s,c,u,l;h.queue=[],m||(0<=y&&T+1<S.length?(a=(y+T+1)%S.length,p(d.replace(/^(.*\/\/)([\w\.]*)(\/.*)$/,function(e,t,n,i){return t+S[a]+i})),T+=1):(f=m=!0,s=d,!0!==cfg.dle&&(c=(t=function(){var e,t={},n=g.connectionString;if(n)for(var i=n.split(";"),a=0;a<i.length;a++){var o=i[a].split("=");2===o.length&&(t[o[0][x]()]=o[1])}return t[I]||(e=(n=t.endpointsuffix)?t.location:null,t[I]="https://"+(e?e+".":"")+"dc."+(n||"services.visualstudio.com")),t}()).instrumentationkey||g.instrumentationKey||"",t=(t=(t=t[I])&&"/"===t.slice(-1)?t.slice(0,-1):t)?t+"/v2/track":g.endpointUrl,t=g.userOverrideEndpointUrl||t,(n=[]).push((i="SDK LOAD Failure: Failed to load Application Insights SDK script (See stack for details)",o=s,u=t,(l=(r=v(c,"Exception")).data).baseType="ExceptionData",l.baseData.exceptions=[{typeName:"SDKLoadFailed",message:i.replace(/\./g,"-"),hasFullStack:!1,stack:i+"\nSnippet failed to load ["+o+"] -- Telemetry is disabled\nHelp Link: https://go.microsoft.com/fwlink/?linkid=2128109\nHost: "+(b&&b.pathname||"_unknown_")+"\nEndpoint: "+u,parsedStack:[]}],r)),n.push((l=s,i=t,(u=(o=v(c,"Message")).data).baseType="MessageData",(r=u.baseData).message='AI (Internal): 99 message:"'+("SDK LOAD Failure: Failed to load Application Insights SDK script (See stack for details) ("+l+")").replace(/\"/g,"")+'"',r.properties={endpoint:i},o)),s=n,c=t,JSON&&((u=C.fetch)&&!cfg.useXhr?u(c,{method:D,body:JSON.stringify(s),mode:"cors"}):XMLHttpRequest&&((l=new XMLHttpRequest).open(D,c),l.setRequestHeader("Content-type","application/json"),l.send(JSON.stringify(s)))))))},a=function(e,t){m||setTimeout(function(){!t&&h.core||i()},500),f=!1},p=function(e){var n=O.createElement(q),e=(n.src=e,t&&(n.integrity=t),n.setAttribute("data-ai-name",E),cfg[w]);return!e&&""!==e||"undefined"==n[w]||(n[w]=e),n.onload=a,n.onerror=i,n.onreadystatechange=function(e,t){"loaded"!==n.readyState&&"complete"!==n.readyState||a(0,t)},cfg.ld&&cfg.ld<0?O.getElementsByTagName("head")[0].appendChild(n):setTimeout(function(){O.getElementsByTagName(q)[0].parentNode.appendChild(n)},cfg.ld||0),n};p(d)}cfg.sri&&(n=o.match(/^((http[s]?:\/\/.*\/)\w+(\.\d+){1,5})\.(([\w]+\.){0,2}js)$/))&&6===n.length?(d="".concat(n[1],".integrity.json"),i="@".concat(n[4]),l=window.fetch,t=function(e){if(!e.ext||!e.ext[i]||!e.ext[i].file)throw Error("Error Loading JSON response");var t=e.ext[i].integrity||null;s(o=n[2]+e.ext[i].file,t)},l&&!cfg.useXhr?l(d,{method:"GET",mode:"cors"}).then(function(e){return e.json()["catch"](function(){return{}})}).then(t)["catch"](r):XMLHttpRequest&&((a=new XMLHttpRequest).open("GET",d),a.onreadystatechange=function(){if(a.readyState===XMLHttpRequest.DONE)if(200===a.status)try{t(JSON.parse(a.responseText))}catch(e){r()}else r()},a.send())):o&&r();try{h.cookie=O.cookie}catch(k){}function e(e){for(;e.length;)!function(t){h[t]=function(){var e=arguments;f||h.queue.push(function(){h[t].apply(h,e)})}}(e.pop())}var c,u,l="track",d="TrackPage",p="TrackEvent",l=(e([l+"Event",l+"PageView",l+"Exception",l+"Trace",l+"DependencyData",l+"Metric",l+"PageViewPerformance","start"+d,"stop"+d,"start"+p,"stop"+p,"addTelemetryInitializer","setAuthenticatedUserContext","clearAuthenticatedUserContext","flush"]),h.SeverityLevel={Verbose:0,Information:1,Warning:2,Error:3,Critical:4},(g.extensionConfig||{}).ApplicationInsightsAnalytics||{});return!0!==g[L]&&!0!==l[L]&&(e(["_"+(c="onerror")]),u=C[c],C[c]=function(e,t,n,i,a){var o=u&&u(e,t,n,i,a);return!0!==o&&h["_"+c]({message:e,url:t,lineNumber:n,columnNumber:i,error:a,evt:C.event}),o},g.autoExceptionInstrumented=!0),h}(cfg.cfg),(C[E]=n).queue&&0===n.queue.length?(n.queue.push(e),n.trackPageView({})):e();})({ src: "https://js.monitor.azure.com/scripts/b/ai.3.gbl.min.js", // name: "appInsights", // Global SDK Instance name defaults to "appInsights" when not supplied // ld: 0, // Defines the load delay (in ms) before attempting to load the sdk. -1 = block page load and add to head. (default) = 0ms load after timeout, // useXhr: 1, // Use XHR instead of fetch to report failures (if available), // dle: true, // Prevent the SDK from reporting load failure log crossOrigin: "anonymous", // When supplied this will add the provided value as the cross origin attribute on the script tag // onInit: null, // Once the application insights instance has loaded and initialized this callback function will be called with 1 argument -- the sdk instance (DON'T ADD anything to the sdk.queue -- As they won't get called) // sri: false, // Custom optional value to specify whether fetching the snippet from integrity file and do integrity check cfg: { // Application Insights Configuration connectionString: "InstrumentationKey=9744aaee-21f7-42b6-95b2-8ebc0f2bcfeb;IngestionEndpoint=https://westus-0.in.applicationinsights.azure.com/;LiveEndpoint=https://westus.livediagnostics.monitor.azure.com/", disableExceptionTracking: true, // Disable the default exception tracking } }); window.appInsights.trackPageView(); </script> </head> <body > <div class="bodyGradient"> <header class="navbar navbar-inverse navbar-static-top"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a href="/" class="navbar-brand">';--</a> </div> <div class="navbar-collapse collapse"> <ul class="nav navbar-nav navbar-right"> <li ><a href="/">Home</a></li> <li ><a href="/NotifyMe" class="notifyOfPwning" data-toggle="modal" data-target="#notifyMeModal" data-remote="false">Notify me</a></li> <li ><a href="/DomainSearch">Domain search</a></li> <li ><a href="/PwnedWebsites">Who's been pwned</a></li> <li ><a href="/Passwords">Passwords</a></li> <li class="dropdown active "> <a href="#" class="dropdown-toggle" data-toggle="dropdown">API</a> <ul class="dropdown-menu"> <li class="active" ><a href="/API/v3">Overview</a></li> <li ><a href="/API/Key">API key</a></li> </ul> </li> <li class="dropdown "> <a href="#" class="dropdown-toggle" data-toggle="dropdown">About</a> <ul class="dropdown-menu"> <li ><a href="/About">Who, what &amp; why</a></li> <li ><a href="/Privacy">Privacy</a></li> <li ><a href="/FAQs">FAQs</a></li> <li ><a href="/Pastes">Pastes</a></li> <li ><a href="/OptOut">Opt-out</a></li> <li><a href="https://twitter.com/haveibeenpwned" rel="noopener">Twitter</a></li> <li><a href="https://www.facebook.com/haveibeenpwned/">Facebook</a></li> <li><a rel="me" href="https://infosec.exchange/@haveibeenpwned">Mastodon</a></li> <li><a href="https://haveibeenpwned.uservoice.com/" rel="noopener">Suggest a feature</a></li> <li><a href="http://feeds.feedburner.com/HaveIBeenPwnedLatestBreaches" rel="noopener"><i class="fa fa-rss"></i> Breaches</a></li> </ul> </li> <li ><a href="/Donate">Donate <i class="fa fa-bitcoin"></i> <i class="fa fa-paypal payPalLogo"></i></a></li> </ul> </div> </div> </header> <div class="secondaryHeader"> <div class="container"> <h1>API v3</h1> <h2> The API allows the list of pwned accounts (email addresses and usernames) to be quickly searched via a RESTful service. </h2> </div> </div> </div> <div class="container"> <h3>Overview</h3> <p> 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. </p> <hr /> <h3>Index</h3> <p> <ul> <li> Overview <ul> <li><a href="#Authorisation">Authorisation</a></li> <li><a href="#APIVersion">Specifying the API version</a></li> <li><a href="#UserAgent">Specifying the user agent</a></li> </ul> </li> <li> Breaches <ul> <li><a href="#BreachesForAccount">Getting all breaches for an account</a></li> <li><a href="#BreachesForDomain">Getting all breached email addresses for a domain</a></li> <li><a href="#SubscribedDomains">Getting all subscribed domains</a></li> <li><a href="#AllBreaches">Getting all breached sites in the system</a></li> <li><a href="#SingleBreach">Getting a single breached site by name</a></li> <li><a href="#MostRecentBreach">Getting the most recently added breach</a></li> <li><a href="#AllDataClasses">Getting all data classes</a></li> <li><a href="#BreachModel">The breach model</a></li> <li><a href="#SampleResponse">Sample breach response</a></li> </ul> </li> <li> Stealer logs <ul> <li><a href="#StealerLogsForEmail">Getting all stealer log domains for an email address</a></li> </ul> </li> <li> Pastes <ul> <li><a href="#PastesForAccount">Getting all pastes for an account</a></li> <li><a href="#PasteModel">The paste model</a></li> <li><a href="#SamplePasteResponse">Sample paste response</a></li> </ul> </li> <li> Subscription <ul> <li><a href="#SubscriptionStatus">Getting the subscription status</a></li> </ul> </li> <li> Pwned Passwords <ul> <li><a href="#PwnedPasswords">Overview</a></li> <li><a href="#SearchingPwnedPasswordsByRange">Searching by a range</a></li> <li><a href="#PwnedPasswordsPadding">Introducing padding</a></li> <li><a href="#PwnedPasswordsIncrementalSearching">Incremental searches</a></li> <li><a href="#PwnedPasswordsNTLM">Searching for NTLM hashes</a></li> <li><a href="#PwnedPasswordsDownload">Downloading all Pwned Passwords hashes</a></li> </ul> </li> <li> Further reading <ul> <li><a href="#ResponseCodes">Response codes</a></li> <li><a href="#TestAccounts">Test accounts</a></li> <li><a href="#HTTPS">HTTPS</a></li> <li><a href="#CORS">Cross-origin resource sharing (CORS)</a></li> <li><a href="#RateLimiting">Rate limiting</a></li> <li><a href="#Abuse">Abuse</a></li> <li><a href="#AcceptableUse">Acceptable use</a></li> <li><a href="#License">License</a></li> </ul> </li> </ul> </p> <hr /> <h3 id="Authorisation">Authorisation</h3> <p> Authorisation is required for all APIs that enable searching HIBP by email address or domain, namely <a href="#BreachesForAccount">retrieving all breaches for an account</a>, <a href="#PastesForAccount">retrieving all pastes for an account</a>, <a href="#BreachesForDomain">retrieving all breached email addresses for a domain</a> and <a href="#StealerLogsForEmail">retrieving all stealer log domains for a breached email addresses</a>. There is no authorisation required for <a href="#PwnedPasswords">the free Pwned Passwords API</a>. An HIBP subscription key is required to make an authorised call and can be obtained on <a href="/API/Key">the API key page</a>. The key is then passed in a &quot;hibp-api-key&quot; header: </p> <pre><code>GET https://haveibeenpwned.com/api/v3/{service}/{parameter} hibp-api-key: [your key]</code></pre> <p>Semantic HTTP response codes are used to indicate the result of the API call:</p> <table class="table table-bordered"> <thead> <tr> <td>Code</td> <td>Description</td> </tr> </thead> <tbody> <tr> <td>401</td> <td>Unauthorised &mdash; the API key provided was not valid</td> </tr> </tbody> </table> <p> Additional information may be present in the response body when an API call fails, for example: </p> <pre><code>Access denied due to missing hibp-api-key.</code></pre> <pre><code>Access denied due to improperly formed hibp-api-key.</code></pre> <pre><code>Access denied due to invalid hibp-api-key.</code></pre> <hr /> <h3 id="APIVersion">Specifying the API version</h3> <p> 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: </p> <pre><code>GET https://haveibeenpwned.com/api/v3/{service}/{parameter}</code></pre> <hr /> <h3 id="UserAgent">Specifying the user agent</h3> <p> 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: </p> <pre><code>GET https://haveibeenpwned.com/api/v3/{service}/{parameter} user-agent: [your app name]</code></pre> <p> 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. </p> <hr /> <h3 id="BreachesForAccount">Getting all breaches for an account</h3> <p> 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 <a href="#Authorisation">an HIBP API key</a> must be passed with the request. </p> <pre><code>GET https://haveibeenpwned.com/api/v3/breachedaccount/{account} hibp-api-key: [your key]</code></pre> <p> 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 <a href="#BreachModel">the full breach model</a>. </p> <pre><code>[ { "Name": "Adobe" }, { "Name": "Gawker" }, { "Name": "Stratfor" } ]</code></pre> <p> The name can then be used to either <a href="#SingleBreach">retrieve a single breach</a> or it can be found in <a href="#AllBreaches">the list of all breaches in the system</a>. If you'd like complete breach data returned in the API call, a non-truncated response can be specified via query string parameter: </p> <table class="table table-bordered"> <thead> <tr> <td>Parameter</td> <td>Example</td> <td>Description</td> </tr> </thead> <tbody> <tr> <td>truncateResponse</td> <td class="text-nowrap">?truncateResponse=false</td> <td> Returns <a href="#BreachModel">the full breach model</a>. </td> </tr> </tbody> </table> <p> Which returns <a href="#BreachModel">the complete model for each breach</a>: </p> <pre><code>[ { "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 with each containing an internal ID, username, email, <em>encrypted</em> password and a password hint in plain text. The password cryptography was poorly done and many were quickly resolved back to plain text. The unencrypted hints also &lt;a href="http://www.troyhunt.com/2013/11/adobe-credentials-and-serious.html" target="_blank" rel="noopener"&gt;disclosed much about the passwords&lt;/a&gt; adding further to the risk that hundreds of millions of Adobe customers already faced.", "LogoPath": "https://logos.haveibeenpwned.com/Adobe.png", "DataClasses": [ "Email addresses", "Password hints", "Passwords", "Usernames" ], "IsVerified": true, "IsFabricated": false, "IsSensitive": false, "IsRetired": false, "IsSpamList": false, "IsMalware": false, "IsStealerLog": false, "IsSubscriptionFree": false }, ...</code></pre> <p> The result set can also be filtered by passing one of the following query strings: </p> <table class="table table-bordered"> <thead> <tr> <td>Parameter</td> <td>Example</td> <td>Description</td> </tr> </thead> <tbody> <tr> <td>domain</td> <td class="text-nowrap">?Domain=adobe.com</td> <td> 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. </td> </tr> </tbody> </table> <p> Note: the public API <em>will not</em> return accounts from any breaches flagged as <a href="/FAQs#SensitiveBreach">sensitive</a> or <a href="/FAQs#RetiredBreach">retired</a>. By default, the API will return breaches flagged as <a href="/FAQs#UnverifiedBreach">unverified</a>, however these can be excluded by using the following parameter: </p> <table class="table table-bordered"> <thead> <tr> <td>Parameter</td> <td>Example</td> <td>Description</td> </tr> </thead> <tbody> <tr> <td>IncludeUnverified</td> <td class="text-nowrap">?IncludeUnverified=false</td> <td> Returns breaches that have been flagged as &quot;unverified&quot;. By default, both verified and unverified breaches are returned when performing a search. </td> </tr> </tbody> </table> <p> If the account <em>is not</em> found in a breach, an HTTP 404 response will be returned. See <a href="#ResponseCodes">the response codes section of the API docs</a> for more information, including other response codes that me be returned. </p> <hr /> <h3 id="BreachesForDomain">Getting all breached email addresses for a domain</h3> <p> 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 <a href="/DomainSearch">domain search dashboard</a> 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 <a href="#Authorisation">an HIBP API key</a>. </p> <pre><code>GET https://haveibeenpwned.com/api/v3/breacheddomain/{domain} hibp-api-key: [your key]</code></pre> <p> If one or more results are found, an HTTP 200 response is returned. For each breached email address on the domain, only the <em>alias</em> 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 <a href="#SingleBreach">retrieve a single breach</a> or it can be found in <a href="#AllBreaches">the list of all breaches in the system</a>. </p> <pre><code>{ "alias1": [ "Adobe" ], "alias2": [ "Adobe", "Gawker", "Stratfor" ], "alias3": [ "AshleyMadison" ] }</code></pre> <p> In the above example, if the domain searched for is example.com then 3 email addresses have been found: </p> <ol> <li>alias1@example.com is in the Adobe data breach</li> <li>alias2@example.com is in the Adobe, Gawker and Stratfor data breaches</li> <li>alias3@example.com is in the Ashley Madison data breach</li> </ol> <p> If the domain <em>does not</em> have any email addresses in any breaches, an HTTP 404 response will be returned. See <a href="#ResponseCodes">the response codes section of the API docs</a> for more information, including other response codes that me be returned. </p> <p> Typically, there is no need to query a domain unless a new breach has been added since the last query. Whilst there's no formal rate limit on the domain search API, reguarly querying it beyond what is practically necessary may result in an HTTP 429 response. To optimise your querying, you can aggressively query <a href="#MostRecentBreach">the unauthenticated most recent breach API</a> (it's heavily cached at Cloudflare) and once a new breach is seen, query the domain search API for each of your domains. </p> <p> Note: the domain search API <em>will</em> return sensitive data breaches as it can only be called after demonstrating control of the domain. </p> <hr /> <h3 id="SubscribedDomains">Getting all subscribed domains</h3> <p> Domains that have been successfully added to the <a href="/DomainSearch">domain search dashboard</a> after verifying control are returned via this API. This is an authenticated API requiring <a href="#Authorisation">an HIBP API key</a> which will then return all domains associated with that key. </p> <pre><code>GET https://haveibeenpwned.com/api/v3/subscribeddomains</code></pre> <p> The API returns a list of subscribed domains including the following attributes: </p> <table class="table table-bordered"> <thead> <tr> <td>Attribute</td> <td>Type</td> <td>Description</td> </tr> </thead> <tbody> <tr> <td>DomainName</td> <td>string</td> <td> The full domain name that has been successfully verified. </td> </tr> <tr> <td>PwnCount</td> <td>integer</td> <td> The total number of breached email addresses found on the domain at last search (will be null if no searches yet performed). </td> </tr> <tr> <td>PwnCountExcludingSpamLists</td> <td>integer</td> <td> The number of breached email addresses found on the domain at last search, excluding any breaches flagged as a <a href="/FAQs#SpamList">spam list</a> (will be null if no searches yet performed). </td> </tr> <tr> <td>PwnCountExcludingSpamLists<br />AtLastSubscriptionRenewal</td> <td>integer</td> <td> The total number of breached email addresses found on the domain when the current subscription was taken out (will be null if no searches yet performed). This number ensures <a href="https://www.troyhunt.com/welcome-to-the-new-have-i-been-pwned-domain-search-subscription-service/">the domain remains searchable throughout the subscription period even if the volume of breached accounts grows beyond the subscription's scope</a>. </td> </tr> <tr> <td>NextSubscriptionRenewal</td> <td>datetime</td> <td> The date and time the current subscription ends in ISO 8601 format. The PwnCountExcludingSpamListsAtLastSubscriptionRenewal value is locked in until this time (will be null if there have been no subscriptions). </td> </tr> </tbody> </table> <hr /> <h3 id="AllBreaches">Getting all breached sites in the system</h3> <p> A &quot;breach&quot; 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 <strong>870 breaches</strong>. </p> <p><a href="/api/v3/breaches" class="btn btn-primary">click here to test</a></p> <pre><code>GET https://haveibeenpwned.com/api/v3/breaches</code></pre> <p> The result set can also be filtered by passing one of the following query strings: </p> <table class="table table-bordered"> <thead> <tr> <td>Parameter</td> <td>Example</td> <td>Test</td> <td>Description</td> </tr> </thead> <tbody> <tr> <td>Domain</td> <td class="text-nowrap">?Domain=adobe.com</td> <td><a href="/api/v3/breaches?Domain=adobe.com" class="btn btn-primary">test</a></td> <td> 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. </td> </tr> <tr> <td>IsSpamList</td> <td class="text-nowrap">?IsSpamList=true</td> <td><a href="/api/v3/breaches?IsSpamList=true" class="btn btn-primary">test</a></td> <td> Filters the result set to only breaches that either are or are not flagged as a spam list. </td> </tr> </tbody> </table> <hr /> <h3 id="SingleBreach">Getting a single breached site by name</h3> <p> Sometimes just a single breach is required and this can be retrieved by the breach &quot;Name&quot;. This is the stable value which may or may not be the same as the breach &quot;Title&quot;, which <em>can</em> change. See <a href="#BreachModel">the breach model</a> below for more info. </p> <p><a href="/api/v3/breach/Adobe" class="btn btn-primary">click here to test</a></p> <pre><code>GET https://haveibeenpwned.com/api/v3/breach/{name}</code></pre> <hr /> <h3 id="MostRecentBreach">Getting the most recently added breach</h3> <p> 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 <em>added</em> breach based on the "AddedDate" attribute of the breach model. This may not be the most recent breach to <em>occur</em> as there may be significant lead time between a service being breached and the data later appearing on HIBP. See <a href="#BreachModel">the breach model</a> below for more info. </p> <p><a href="/api/v3/latestbreach" class="btn btn-primary">click here to test</a></p> <pre><code>GET https://haveibeenpwned.com/api/v3/latestbreach</code></pre> <hr /> <h3 id="AllDataClasses">Getting all data classes in the system</h3> <p> A &quot;data class&quot; is an attribute of a record compromised in a breach. For example, many breaches expose data classes such as &quot;Email addresses&quot; and &quot;Passwords&quot;. 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. </p> <p><a href="/api/v3/dataclasses" class="btn btn-primary">click here to test</a></p> <pre><code>GET https://haveibeenpwned.com/api/v3/dataclasses</code></pre> <hr /> <h3 id="BreachModel">The breach model</h3> <p> Each breach contains a number of attributes describing the incident. In the future, these attributes may expand <em>without</em> the API being versioned. The current attributes are: </p> <table class="table table-bordered"> <thead> <tr> <td>Attribute</td> <td>Type</td> <td>Description</td> </tr> </thead> <tbody> <tr> <td>Name</td> <td>string</td> <td> 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 &quot;Title&quot; attribute instead). </td> </tr> <tr> <td>Title</td> <td>string</td> <td> 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 &quot;Name&quot; attribute instead. </td> </tr> <tr> <td>Domain</td> <td>string</td> <td> 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. </td> </tr> <tr> <td>BreachDate</td> <td>date</td> <td> The date (with no time) the breach originally occurred on in ISO 8601 format. This is not always accurate &mdash; frequently breaches are discovered and reported long after the original incident. Use this attribute as a guide only. </td> </tr> <tr> <td>AddedDate</td> <td>datetime</td> <td> The date and time (precision to the minute) the breach was added to the system in ISO 8601 format. </td> </tr> <tr> <td>ModifiedDate</td> <td>datetime</td> <td> The date and time (precision to the minute) the breach was <em>modified</em> in ISO 8601 format. This will only differ from the AddedDate attribute if other attributes represented here are changed or data in the breach itself is changed (i.e. additional data is identified and loaded). It is always either equal to or greater then the AddedDate attribute, never less than. </td> </tr> <tr> <td>PwnCount</td> <td>integer</td> <td> The total number of accounts loaded into the system. This is usually less than the total number reported by the media due to duplication or other data integrity issues in the source data. </td> </tr> <tr> <td>Description</td> <td>string</td> <td> Contains an overview of the breach represented in HTML markup. The description may include markup such as emphasis and strong tags as well as hyperlinks. </td> </tr> <tr> <td>DataClasses</td> <td>string[]</td> <td> This attribute describes the nature of the data compromised in the breach and contains an alphabetically ordered string array of impacted data classes. </td> </tr> <tr> <td>IsVerified</td> <td>boolean</td> <td> Indicates that the breach is considered <a href="/FAQs#UnverifiedBreach">unverified</a>. An unverified breach <em>may not</em> have been hacked from the indicated website. An unverified breach is still loaded into HIBP when there's sufficient confidence that a significant portion of the data is legitimate. </td> </tr> <tr> <td>IsFabricated</td> <td>boolean</td> <td> Indicates that the breach is considered <a href="/FAQs#FabricatedBreach">fabricated</a>. A fabricated breach is <em>unlikely</em> to have been hacked from the indicated website and usually contains a large amount of manufactured data. However, it still contains legitimate email addresses and asserts that the account owners were compromised in the alleged breach. </td> </tr> <tr> <td>IsSensitive</td> <td>boolean</td> <td> Indicates if the breach is considered <a href="/FAQs#SensitiveBreach">sensitive</a>. The public API <em>will not</em> return any accounts for a breach flagged as sensitive. </td> </tr> <tr> <td>IsRetired</td> <td>boolean</td> <td> Indicates if the breach has been <a href="/FAQs#RetiredBreach">retired</a>. This data has been permanently removed and will not be returned by the API. </td> </tr> <tr> <td>IsSpamList</td> <td>boolean</td> <td> Indicates if the breach is considered a <a href="/FAQs#SpamList">spam list</a>. 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. </td> </tr> <tr> <td>IsMalware</td> <td>boolean</td> <td> Indicates if the breach is <a href="/FAQs#Malware">sourced from malware</a>. This flag has no impact on any other attributes, it merely flags that the data was sourced from a malware campaign rather than a security compromise of an online service. </td> </tr> <tr> <td>IsSubscriptionFree</td> <td>boolean</td> <td> Indicates if the breach is <a href="/FAQs#SubscriptionFreeBreach">subscription free</a>. This flag has no impact on any other attributes, it is only used when running a domain search where a sufficiently sized subscription isn't present. </td> </tr> <tr> <td>IsStealerLog</td> <td>boolean</td> <td> Indicates if the breach is <a href="/FAQs#StealerLogs">sourced from stealer logs</a>. A breach with this flag also has the domains that appear in the logs loaded against each email address. This data can be accessed via <a href="#StealerLogsForEmail">the stealer logs API</a>. </td> </tr> <tr> <td>LogoPath</td> <td>string</td> <td> A URI that specifies where a logo for the breached service can be found. Logos are always in PNG format. </td> </tr> </tbody> </table> <hr /> <h3 id="SampleResponse">Sample breach response</h3> <p> All responses return breach models either in a collection (breaches for account or all breaches in the system) or as a single item (retrieving a breach by name). When a collection is returned, it's sorted alphabetically by the <em>title</em> of the breach. </p> <pre><code>[ { "Name":"Adobe", "Title":"Adobe", "Domain":"adobe.com", "BreachDate":"2013-10-04", "AddedDate":"2013-12-04T00:00Z", "ModifiedDate":"2022-05-15T23:52Z", "PwnCount":152445165, "Description":"In October 2013, 153 million Adobe accounts were breached with each containing an internal ID, username, email, &lt;em&gt;encrypted&lt;/em&gt; password and a password hint in plain text. The password cryptography was poorly done and many were quickly resolved back to plain text. The unencrypted hints also &lt;a href=\&quot;http://www.troyhunt.com/2013/11/adobe-credentials-and-serious.html\&quot; target=\&quot;_blank\&quot; rel=\&quot;noopener\&quot;&gt;disclosed much about the passwords&lt;/a&gt; adding further to the risk that hundreds of millions of Adobe customers already faced.", "DataClasses":[&quot;Email addresses&quot;,&quot;Password hints&quot;,&quot;Passwords&quot;,&quot;Usernames&quot;], "IsVerified":true, "IsFabricated":false, "IsSensitive":false, "IsRetired":false, "IsSpamList":false, "IsMalware":false, "IsSubscriptionFree":false, "LogoPath":"https://logos.haveibeenpwned.com/Adobe.png" }, { "Name":"BattlefieldHeroes", "Title":"Battlefield Heroes", "Domain":"battlefieldheroes.com", "BreachDate":"2011-06-26", "AddedDate":"2014-01-23T13:10Z", "ModifiedDate":"2014-01-23T13:10Z", "PwnCount":530270, "Description":"In June 2011 as part of a final breached data dump, the hacker collective &amp;quot;LulzSec&amp;quot; &lt;a href=\&quot;http://www.rockpapershotgun.com/2011/06/26/lulzsec-over-release-battlefield-heroes-data\&quot; target=\&quot;_blank\&quot; rel=\&quot;noopener\&quot;&gt;obtained and released over half a million usernames and passwords from the game Battlefield Heroes&lt;/a&gt;. The passwords were stored as MD5 hashes with no salt and many were easily converted back to their plain text versions.", "DataClasses":[&quot;Passwords&quot;,&quot;Usernames&quot;], "IsVerified":true, "IsFabricated":false, "IsSensitive":false, "IsRetired":false, "IsSpamList":false, "IsMalware":false, "IsSubscriptionFree":false, "LogoPath":"https://logos.haveibeenpwned.com/BattlefieldHeroes.png" } ]</code></pre> <hr /> <h3 id="StealerLogsForEmail">Getting all stealer log domains for an email address</h3> <p> Stealer logs typically appear as a combination of email address, password and the website they were entered into. HIBP stores the domain names of those websites and makes them queryable via the email address they appeared next to. For example, if test@example.com appeared in stealer logs against netflix.com and spotify.com, the two streaming media domains can be returned by searching this API for test@example.com. </p> <pre><code>GET https://haveibeenpwned.com/api/v3/stealerlogsbyemail/{email address} hibp-api-key: [your key]</code></pre> <p> This search returns an array of domains sorted alphabetically: </p> <pre><code>[ "netflix.com", "spotify.com" ]</code></pre> <p> Note: The email address being searched for <em>must be on a domain already added to the <a href="/DomainSearch">domain search dashboard</a></em>. In this case, it requires adding example.com to the dashboard and successfully demonstrating control of this domain. <a href="https://www.troyhunt.com/experimenting-with-stealer-logs-in-have-i-been-pwned">Read more about stealer logs in HIBP.</a> </p> <hr /> <h3 id="PastesForAccount">Getting all pastes for an account</h3> <p> The API takes a single parameter which is the email address to be searched for. The address is not case-sensitive and will be trimmed of leading or trailing white spaces. The address should always be URL encoded. This is an authenticated API and <a href="#Authorisation">an HIBP API key</a> must be passed with the request. </p> <pre><code>GET https://haveibeenpwned.com/api/v3/pasteaccount/{account} hibp-api-key: [your key]</code></pre> <hr /> <h3 id="PasteModel">The paste model</h3> <p> Each paste contains a number of attributes describing it. In the future, these attributes may expand <em>without</em> the API being versioned. The current attributes are: </p> <table class="table table-bordered"> <thead> <tr> <td>Attribute</td> <td>Type</td> <td>Description</td> </tr> </thead> <tbody> <tr> <td>Source</td> <td>string</td> <td> The paste service the record was retrieved from. Current values are: Pastebin, Pastie, Slexy, Ghostbin, QuickLeak, JustPaste, AdHocUrl, PermanentOptOut, OptOut </td> </tr> <tr> <td>Id</td> <td>string</td> <td> The ID of the paste as it was given at the source service. Combined with the &quot;Source&quot; attribute, this can be used to resolve the URL of the paste. </td> </tr> <tr> <td>Title</td> <td>string</td> <td> The title of the paste as observed on the source site. This may be null and if so will be omitted from the response. </td> </tr> <tr> <td>Date</td> <td>date</td> <td> The date and time (precision to the second) that the paste was posted. This is taken directly from the paste site <em>when this information is available</em> but may be null if no date is published. </td> </tr> <tr> <td>EmailCount</td> <td>integer</td> <td> The number of emails that were found when processing the paste. Emails are extracted by using the regular expression \b[a-zA-Z0-9\.\-_\+]+@[a-zA-Z0-9\.\-_]+\.[a-zA-Z]+\b </td> </tr> </tbody> </table> <hr /> <h3 id="SamplePasteResponse">Sample paste response</h3> <p> Searching an account for pastes always returns a collection of the paste entity. The collection is sorted chronologically with the <em>newest</em> paste first. </p> <pre><code>[ { "Source":"Pastebin", "Id":"8Q0BvKD8", "Title":"syslog", "Date":"2014-03-04T19:14:54Z", "EmailCount":139 }, { "Source":"Pastie", "Id":"7152479", "Date":"2013-03-28T16:51:10Z", "EmailCount":30 } ]</code></pre> <hr /> <h3 id="SubscriptionStatus">Getting the subscription status</h3> <p> This API returns details of the current subscription and is an authenticated API requiring <a href="#Authorisation">an HIBP API key</a>: </p> <pre><code>GET https://haveibeenpwned.com/api/v3/subscription/status</code></pre> <p> The API returns the following attributes for the current subscription: </p> <table class="table table-bordered"> <thead> <tr> <td>Attribute</td> <td>Type</td> <td>Description</td> </tr> </thead> <tbody> <tr> <td>SubscriptionName</td> <td>string</td> <td> The name representing the subscription being either &quot;Pwned 1&quot;, &quot;Pwned 2&quot;, &quot;Pwned 3&quot; or &quot;Pwned 4&quot;. </td> </tr> <tr> <td>Description</td> <td>string</td> <td> A human readable sentence explaining the scope of the subscription. </td> </tr> <tr> <td>SubscribedUntil</td> <td>datetime</td> <td> The date and time the current subscription ends in ISO 8601 format. </td> </tr> <tr> <td>Rpm</td> <td>integer</td> <td> The rate limit in requests per minute. This applies to the rate the <a href="#BreachesForAccount">breach search by email address</a> API can be requested. </td> </tr> <tr> <td>DomainSearchMaxBreachedAccounts</td> <td>integer</td> <td> The size of the largest domain the subscription can search. This is expressed in the total number of breached accounts on the domain, excluding those that appear solely in <a href="/FAQs#SpamLists">spam list</a>. </td> </tr> </tbody> </table> <hr /> <h3 id="PwnedPasswords">Pwned Passwords overview</h3> <p> Pwned Passwords are hundreds of millions of passwords which have previously been exposed in data breaches. The service is detailed in <a href="https://www.troyhunt.com/introducing-306-million-freely-downloadable-pwned-passwords/">the launch blog post</a> and most recently <a href="https://www.troyhunt.com/open-source-pwned-passwords-with-fbi-feed-and-225m-new-nca-passwords-is-now-live/"> in this post about the FBI and NCA feeding data into the service. </a>. The data is <a href="/Passwords">queryable online via the Pwned Passwords webpage</a>, accessible via the API or downloadable as an entire corpus of data that can be queried offline. The Pwned Passwords API is freely accessible without the need for a subscription and API key. </p> <p> Each password is stored as both a SHA-1 and an NTLM hash of a UTF-8 encoded password. The downloadable source data delimits the hash and the password count with a colon (:) and each line with a CRLF. </p> <hr /> <h3 id="SearchingPwnedPasswordsByRange">Searching by range</h3> <p> In order to protect the value of the source password being searched for, Pwned Passwords also implements a <a href="https://en.wikipedia.org/wiki/K-anonymity">k-Anonymity model</a> that allows a password to be searched for by partial hash. This allows the first 5 characters of either a SHA-1 or an NTLM hash (not case-sensitive) to be passed to the API: </p> <p><a href="https://api.pwnedpasswords.com/range/21BD1" class="btn btn-primary">click here to test</a></p> <pre><code>GET https://api.pwnedpasswords.com/range/{first 5 hash chars}</code></pre> <p> 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 <em>suffix</em> 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 of the response for the presence of their source hash and if not found, the password does not exist in the data set. A sample SHA-1 response for the hash prefix "21BD1" would be as follows: </p> <pre><code>0018A45C4D1DEF81644B54AB7F969B88D65:1 00D4F6E8FA6EECAD2A3AA415EEC418D38EC:2 011053FD0102E94D6AE2F8B83D76FAF94F6:1 012A7CA357541F0AC487871FEEC1891C49C:2 0136E006E24E7D152139815FB0FC6A50B15:2 ...</code></pre> <p> A range search typically returns approximately 800 hash suffixes, although this number will differ depending on the hash prefix being searched for and will increase as more passwords are added. There are 1,048,576 different hash prefixes between 00000 and FFFFF (16^5) and every single one will return HTTP 200; there is no circumstance in which the API should return HTTP 404. </p> <table class="table table-bordered"> <thead> <tr> <td>Code</td> <td>Body</td> <td>Description</td> </tr> </thead> <tbody> <tr> <td>200</td> <td>Hash suffixes &nbsp; counts</td> <td> Ok &mdash; all password hashes beginning with the searched prefix are returned alongside prevalence counts </td> </tr> </tbody> </table> <p> <a href="https://www.troyhunt.com/ive-just-launched-pwned-passwords-version-2">Read more about how k-Anonymity and the Pwned Passwords range search protects searched passwords.</a> </p> <hr /> <h3 id="PwnedPasswordsPadding">Introducing padding</h3> <p> In order to further enhance privacy, padding can be added to responses such that anyone able to intercept encrypted responses to the API cannot reasonably determine which hash prefix was searched for by observing the response size. Padding is enabled by a request header and ensures that all responses contain between 800 and 1,000 results regardless of the number of hash suffixes returned by the service. <a href="https://www.troyhunt.com/enhancing-pwned-passwords-privacy-with-padding">Read the full blog post on padding.</a> </p> <table class="table table-bordered"> <thead> <tr> <td>Header</td> <td>Example</td> <td>Description</td> </tr> </thead> <tbody> <tr> <td class="text-nowrap">Add-Padding</td> <td class="text-nowrap">Add-Padding: true</td> <td> Pads out responses to ensure all results contain a random number of records between 800 and 1,000. </td> </tr> </tbody> </table> <p> Note: Padded entries always have a password count of 0 and can be discarded once received. </p> <hr /> <h3 id="PwnedPasswordsIncrementalSearching">Incremental searching</h3> <p> Incremental searching involves performing a search for the password as each character is typed by the user, for example via an asynchronous request from their browser. <a href="https://blog.quarkslab.com/passbolt-a-bold-use-of-haveibeenpwned.html">This may provide a 3rd party (namely someone with access to view inbound requests at Cloudflare) with the ability to observe the API requests with sufficient information to discern the original password being searched for</a>. Waiting until the entire password is entered before checking Pwned Passwords (for example, when <a href="https://developer.mozilla.org/en-US/docs/Web/API/Element/blur_event">the blur event</a> is raised on the password field), mitigates this risk. </p> <hr /> <h3 id="PwnedPasswordsNTLM">Searching for NTLM hashes</h3> <p> Whilst Pwned Passwords defaults to SHA-1, password hashes can also be requested in NTLM form. API requests still pass the first 5 characters of the hash, but the response returns NTLM hash suffixes of 27 characters rather than SHA-1 suffixes of 35 characters (an NTLM hash is 8 characters shorter than a SHA-1 equivalent). The hash format can be specified via the mode query string: </p> <table class="table table-bordered"> <thead> <tr> <td>Parameter</td> <td>Example</td> <td>Description</td> </tr> </thead> <tbody> <tr> <td class="text-nowrap">mode</td> <td class="text-nowrap">?mode=ntlm</td> <td> Returns NTLM hash suffixes. When the mode is not specified or is any value other than &quot;ntlm&quot;, the resulting hashes will be in SHA-1 form. </td> </tr> </tbody> </table> <hr /> <h3 id="PwnedPasswordsDownload">Downloading all Pwned Passwords hashes</h3> <p> Pwned Passwords works best when directly querying the k-Anonymity API; it's fast, always up to date and enables anonymous queries without disclosing the password being searched for. However, all password hashes are also available for download as either SHA-1 or NTLM so they can be used without the API dependency. The <a href="https://github.com/HaveIBeenPwned/PwnedPasswordsDownloader">Pwned Passwords Downloader</a> is freely available from GitHub and enables the API to be queried for every single hash prefix and the results saved offline. <a href="https://www.troyhunt.com/downloading-pwned-passwords-hashes-with-the-hibp-downloader/">Read more in the launch blog post.</a> </p> <hr /> <h3 id="HTTPS">HTTPS</h3> <p> All API endpoints must be invoked over HTTPS. Any requests over HTTP will result in a 301 response with a redirect to the same path on the secure scheme. Only TLS versions 1.2 and 1.3 are supported; older versions of the protocol will not allow a connection to be made. </p> <hr /> <h3 id="ResponseCodes">Response codes</h3> <p>Semantic HTTP response codes are used to indicate the result of the search:</p> <table class="table table-bordered"> <thead> <tr> <td>Code</td> <td>Description</td> </tr> </thead> <tbody> <tr> <td>200</td> <td> Ok &mdash; everything worked and there's a string array of pwned sites for the account </td> </tr> <tr> <td>400</td> <td> Bad request &mdash; the account does not comply with an acceptable format (i.e. it's an empty string) </td> </tr> <tr> <td>401</td> <td>Unauthorised — either no API key was provided or it wasn't valid</td> </tr> <tr> <td>403</td> <td>Forbidden &mdash; no user agent has been specified in the request</td> </tr> <tr> <td>404</td> <td>Not found &mdash; the account could not be found and has therefore not been pwned</td> </tr> <tr> <td>429</td> <td>Too many requests &mdash; the <a href="#RateLimiting">rate limit</a> has been exceeded</td> </tr> <tr> <td>503</td> <td> Service unavailable &mdash; usually returned by Cloudflare if the underlying service is not available </td> </tr> </tbody> </table> <hr /> <h3 id="TestAccounts">Test accounts</h3> <p> Test accounts exist to demonstrate different behaviours. All accounts are on the domain &quot;hibp-integration-tests.com&quot;, for example &quot;account-exists@hibp-integration-tests.com&quot;. </p> <table class="table table-bordered"> <thead> <tr> <td>Alias</td> <td>Description</td> </tr> </thead> <tbody> <tr> <td>account-exists</td> <td> Returns one breach and one paste. </td> </tr> <tr> <td>multiple-breaches</td> <td> Returns three breaches. </td> </tr> <tr> <td>not-active-and-active-breach</td> <td> Returns one breach being &quot;Adobe&quot;. An inactive breach also exists against this account in the underlying data structure. </td> </tr> <tr> <td>not-active-breach</td> <td> Returns no breaches. An inactive data breach also exists against this account in the underlying data structure. </td> </tr> <tr> <td>opt-out</td> <td> Returns no breaches and no pastes. This account is opted-out of both pastes and breaches in the underlying data structure. </td> </tr> <tr> <td>opt-out-breach</td> <td> Returns no breaches and no pastes. This account is opted-out of breaches in the underlying data structure. </td> </tr> <tr> <td>paste-sensitive-breach</td> <td> Returns no breaches and one paste. A sensitive breach exists against this account in the underlying data structure. </td> </tr> <tr> <td>permanent-opt-out</td> <td> Returns no breaches and no pastes. This account is permanently opted-out of both breaches and pastes in the underlying data structure. </td> </tr> <tr> <td>sensitive-and-other-breaches</td> <td> Returns two non-sensitive breaches and no pastes. A sensitive breach exists against this account in the underlying data structure. </td> </tr> <tr> <td>sensitive-breach</td> <td> Returns no breaches and no pastes. A sensitive breach exists against this account in the underlying data structure. </td> </tr> <tr> <td>spam-list-only</td> <td> Returns a single breach that has been flagged as a <a href="/FAQs#SpamList">spam list</a>. </td> </tr> <tr> <td>spam-list-and-others</td> <td> Returns multiple breaches, one of which has been flagged as a <a href="/FAQs#SpamList">spam list</a>. </td> </tr> <tr> <td>subscription-free-and-other-breaches</td> <td> Returns a breach flagged as <a href="/FAQs#SubscriptionFreeBreach">subscription free</a> and two other breaches that aren't. </td> </tr> <tr> <td>stealer-log</td> <td> Returns a single stealer log breach and also contains a single domain that has appeared against this address in a stealer log. </td> </tr> <tr> <td>subscription-free-breach</td> <td> Returns a single breach flagged as <a href="/FAQs#SubscriptionFreeBreach">subscription free</a>. </td> </tr> <tr> <td>unverified-breach</td> <td> Returns one unverified breach and no pastes. </td> </tr> </tbody> </table> <hr /> <h3 id="CORS">Cross-origin resource sharing (CORS)</h3> <p> <a href="https://en.wikipedia.org/wiki/Cross-origin_resource_sharing">CORS</a> 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. </p> <p> On supported APIs, CORS accepts all origins &mdash; you can hit the API from websites on any other domain. </p> <hr /> <h3 id="RateLimiting">Rate limiting</h3> <p> Requests to the breaches, pastes and stealer log APIs are rate limited. The rate limits depends on the <a href="/API/Key">the API key you've purchased</a>. Any request that exceeds the limit will receive an <a href="https://httpstatuses.com/429">HTTP 429 &quot;Too many requests&quot;</a> response. The response also includes an accompanying &quot;retry-after&quot; 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 <a href="#AcceptableUse">acceptable use</a> documentation. </p> <p> A typical response looks like this: </p> <pre><code>HTTP/1.1 429 retry-after: 2 { "statusCode": 429, "message": "Rate limit is exceeded. Try again in 2 seconds." }</code></pre> <p> 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. </p> <p> 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. </p> <p> 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 &quot;Service Unavailable&quot; response. </p> <p> There is no rate limit on the Pwned Passwords API. </p> <hr /> <h3 id="Abuse">Abuse</h3> <p> 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: </p> <hr /> <h3 id="AcceptableUse">Acceptable use</h3> <p> The API has been designed to make it easy for people to do <em>awesome</em> things with it. Things that are <em>not</em> awesome include: </p> <ul> <li>Querying the data for purposes that are intended to cause harm to the victims of data breaches</li> <li>Anything deliberately intended to limit service availability such as denial of service attacks</li> <li>Deliberate attempts to circumvent measures designed to ensure acceptable use</li> <li>Not <a href="#UserAgent">properly identifying the user agent</a> such that it accurately describes the consumer of the API</li> <li>Misrepresenting the consuming client by impersonating other user agents in an attempt to obfuscate API requests</li> <li>Other services designed to fraudulently represent the Have I Been Pwned name or brand</li> <li>Misrepresenting the source of the data as originating from somewhere other than Have I Been Pwned</li> <li>Not adhering to the Creative Commons Attribution License <a href="#AcceptableUse">as described below</a></li> <li>Automating the consumption of other APIs not explicitly documented on this page</li> <li>Using the service in a fashion that brings Have I Been Pwned into disrepute</li> </ul> <p> 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, <a href="https://www.troyhunt.com/contact/">get in touch</a> and outline how you'd like to use the service in a way that's consistent with these objectives. </p> <hr /> <h3 id="License">License &mdash; breach &amp; paste APIs</h3> <p> This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License</a>. </p> <p> <a rel="license" href="http://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons License" style="border-width: 0" src="/Content/Images/CreativeCommons.png" /></a> </p> <p> In other words, you're welcome to use the public API to build other services, but <em>you must identify Have I Been Pwned as the source of the data</em>. Clear and visible attribution with a link to <a href="https://haveibeenpwned.com/">haveibeenpwned.com</a> 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 <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License</a>. </p> <p> 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. </p> </div> <div class="modal fade" id="notifyMeModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button> <h4 class="modal-title">Notify me</h4> </div> <div class="modal-body" id="notifyMeContainer"> <div class="panel-collapse in" id="notifySubmission"> <form action="/api/NotifyMe" id="notifyMeForm" method="post" role="form"> <p> Get notified when future pwnage occurs and your account is compromised. </p> <div class="form-group row"> <div class="col-lg-7"> <input class="form-control" data-val="true" data-val-maxlength="The field Email must be a string or array type with a maximum length of &#39;255&#39;." data-val-maxlength-max="255" data-val-regex="That doesn&#39;t look like a valid email address" data-val-regex-pattern="^(?!^.{256})[^\x00-\x1F\*\x7F]+@[^\x00-\x1F\*\x7F]+$" data-val-required="Can&#39;t do much without an email address" id="NotifyEmail" maxlength="255" name="NotifyEmail" placeholder="enter your email address" type="email" value="" /> </div> </div> <div class="form-group row"> <script src="https://www.google.com/recaptcha/api.js" async defer></script> <div class="g-recaptcha" data-sitekey="6Lcb0woTAAAAAJAbo3ToF_yAJMKMsZgSATbQTRmI"></div> </div> <div class="form-group row"> <p class="termsOfUse">Using Have I Been Pwned is subject to <a href="/TermsOfUse" target="_blank">the terms of use</a></p> </div> <div class="validation-summary-valid alert alert-danger" data-valmsg-summary="true" id="notifyError"><ul><li style="display:none"></li> </ul></div> <div class="form-group row" id="notificationSubmitRow"> <input type="submit" value="notify me of pwnage" class="btn btn-primary" /><i class="fa fa-3x fa-cog fa-spin fa-loader" id="notificationLoading" style="display: none;"></i> </div> </form> </div> <div class="panel-collapse collapse" id="notifySuccess"> <p> You've just been sent a verification email, all you need to do now is confirm your address by clicking on the link when it hits your mailbox and you'll be automatically notified of future pwnage. In case it doesn't show up, check your junk mail and if you <em>still</em> can't find it, you can always repeat this process. </p> <hr /> <p class="text-center" id="postNotificationCallsToAction"> <a class="btn btn-primary" id="addAnotherNotification">add another address</a> <a class="socialLink" href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fhaveibeenpwned.com" rel="noopener"><i class="fa fa-facebook-square fa-3x"></i></a> <a class="socialLink" href="https://twitter.com/intent/tweet?url=https%3A%2F%2Fhaveibeenpwned.com&amp;text=Have%20you%20been%20pwned%3F%20Get%20told%20when%20you%20are%20with%20a%20free%20%40haveibeenpwned%20subscription" rel="noopener"><i class="fa fa-twitter-square fa-3x"></i></a> </p> </div> </div> </div> </div> </div> <footer> <div class="container text-center"> <hr /> <p> <a href="/Privacy">Privacy policy</a> | <a href="/TermsOfUse">Terms of use</a> </p> <p> <a href="https://www.facebook.com/haveibeenpwned" rel="noopener"><i class="fa fa-facebook-square fa-3x"></i></a> <a href="https://twitter.com/haveibeenpwned" rel="noopener"><i class="fa fa-twitter-square fa-3x"></i></a> <a href="https://www.troyhunt.com/contact/" rel="noopener"><i class="fa fa-envelope fa-3x"></i></a> </p> </div> </footer> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js" integrity="sha512-v2CJ7UaYy4JwqLDIrZUI/4hqeoQieOmAZNXBeQyjo21dadnwR+8ZaIJVT8EE2iyI61OV8e6M8PP2/4hpQINQ/g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <script nonce="KJ8+IZ/8bM7NArC0SgLT/RkE">(window.jQuery) || document.write('<script src="/scripts/jquery"><\/script>');</script> <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha512-oBTprMeNEKCnqfuqKd6sbvFzmFQtlXS3e0C/RGFV0hD6QzhHV+ODfaQbAlmY6/q0ubbwlAM/nCJjkrgA3waLzg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <script nonce="KJ8+IZ/8bM7NArC0SgLT/RkE">($.fn.modal) || document.write('<script src="/scripts/bootstrap"><\/script>');</script> <script src="/scripts/pwned?v=KkF8OaBJocrSdvf45kkWgo5tWa402SohbJylL0Etpeg1"></script> </body> </html>

Pages: 1 2 3 4 5 6 7 8 9 10