Password Breaches
curl --request POST \
--url https://developer.encrata.com/api/lookup/email/password/breaches \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"sha1": "<string>",
"password": "<string>"
}
'import requests
url = "https://developer.encrata.com/api/lookup/email/password/breaches"
payload = {
"sha1": "<string>",
"password": "<string>"
}
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({sha1: '<string>', password: '<string>'})
};
fetch('https://developer.encrata.com/api/lookup/email/password/breaches', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://developer.encrata.com/api/lookup/email/password/breaches",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'sha1' => '<string>',
'password' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://developer.encrata.com/api/lookup/email/password/breaches"
payload := strings.NewReader("{\n \"sha1\": \"<string>\",\n \"password\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://developer.encrata.com/api/lookup/email/password/breaches")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"sha1\": \"<string>\",\n \"password\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://developer.encrata.com/api/lookup/email/password/breaches")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"sha1\": \"<string>\",\n \"password\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"prefix": "5BAA6",
"found": true,
"count": 52372427,
"message": "This password has appeared in known breaches.",
"credits": 1
}
{ "code": "insufficient_credits", "error": "You don't have enough credits for this lookup. Top up to continue." }
Breaches
Password Breaches
Check whether a password has appeared in known data breaches, privately, via HIBP k-anonymity.
POST
/
api
/
lookup
/
email
/
password
/
breaches
Password Breaches
curl --request POST \
--url https://developer.encrata.com/api/lookup/email/password/breaches \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"sha1": "<string>",
"password": "<string>"
}
'import requests
url = "https://developer.encrata.com/api/lookup/email/password/breaches"
payload = {
"sha1": "<string>",
"password": "<string>"
}
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({sha1: '<string>', password: '<string>'})
};
fetch('https://developer.encrata.com/api/lookup/email/password/breaches', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://developer.encrata.com/api/lookup/email/password/breaches",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'sha1' => '<string>',
'password' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://developer.encrata.com/api/lookup/email/password/breaches"
payload := strings.NewReader("{\n \"sha1\": \"<string>\",\n \"password\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://developer.encrata.com/api/lookup/email/password/breaches")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"sha1\": \"<string>\",\n \"password\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://developer.encrata.com/api/lookup/email/password/breaches")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"sha1\": \"<string>\",\n \"password\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"prefix": "5BAA6",
"found": true,
"count": 52372427,
"message": "This password has appeared in known breaches.",
"credits": 1
}
{ "code": "insufficient_credits", "error": "You don't have enough credits for this lookup. Top up to continue." }
Overview
Password Breaches tells you whether a password has appeared in known data breaches, and how many times, without ever transmitting or storing the plaintext password. It’s built for a sign-up / password-reset guard: warn a user when the password they chose has already leaked and prompt them to pick a different one. It uses the k-anonymity model on top of Have I Been Pwned’s Pwned Passwords corpus: the password is SHA-1 hashed and only the first 5 hex characters of the hash are ever sent to the upstream service. There are two ways to run it:- Single check (
POST /api/lookup/email/password/breaches): the API-key endpoint documented on this page, for programmatic access (e.g. your sign-up backend). - Batches (
POST /api/jobs/bulkwithtype=password-breaches): a background job for up to 1,000,000 SHA-1 hashes. See Check many passwords.
The plaintext password is never stored. History records only a masked label
(a dotted mask plus the 5-char hash prefix), never the password or its full hash.
Authentication
Requires an API key in theAuthorization header.
Authorization: Bearer enc_xxxxxxxxxxxx
Request
Sendsha1 (recommended) or password. If you send both, sha1 wins and
password is ignored.
string
Upper-case hex SHA-1 of the password. Must be exactly 40 hex characters;
surrounding whitespace is trimmed and lowercase hex is upper-cased for you.
Preferred: the plaintext never leaves the caller. Only the first 5 hex chars
are sent upstream.
string
The raw password to check. Hashed server-side (SHA-1) immediately and never
stored; only the 5-char hash prefix leaves the server. Prefer
sha1 in
production.Example request
curl -X POST "https://developer.encrata.com/api/lookup/email/password/breaches" \
-H "Authorization: Bearer enc_xxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"sha1": "5BAA61E4C9B93F3F0682250B6CF8331B7EE68FD8"}'
Response
string
The 5-char SHA-1 hash prefix used for the k-anonymity query.
boolean
Whether the password appears in any known breach.
number
How many times the password has been seen across breaches.
string
Human-readable summary of the verdict.
number
Credits charged for this request.
1 on the first check, or 0 when you
already checked this password during the
6-month free-repeat window.Errors
Errors return a JSON body of the form{"error": "<message>", "code": "<code>"}
with the matching HTTP status code.
| Status | Message | Cause |
|---|---|---|
400 | bad body | Malformed JSON |
400 | Provide a SHA-1 password hash (sha1) or a password | Neither sha1 nor password supplied |
400 | Provide a SHA-1 password hash (sha1) or a password | sha1 is not 40 hexadecimal characters |
401 | bad key | Missing or invalid API key |
402 | You don't have enough credits for this lookup. Top up to continue. | No credits remaining |
405 | Only POST method is allowed | Wrong HTTP method |
413 | body too large | Request body exceeds 1 MiB |
500 | internal error | Unexpected server failure |
502 | password breach lookup failed | Transient upstream error, retry shortly |
503 | password breach service unavailable | Breach corpus not configured |
{
"prefix": "5BAA6",
"found": true,
"count": 52372427,
"message": "This password has appeared in known breaches.",
"credits": 1
}
{ "code": "insufficient_credits", "error": "You don't have enough credits for this lookup. Top up to continue." }
Check many passwords
To check many passwords, upload SHA-1 hashes withPOST /api/jobs/bulk
(type=password-breaches) and download the result with kind=password.
POST /api/jobs/bulk runs in the background and handles up to 1,000,000
hashes. SHA-1 hash every password client-side first, so plaintext never
reaches the server. A webhook delivers the finished file.
curl -X POST "https://developer.encrata.com/api/jobs/bulk" \
-H "Authorization: Bearer enc_xxxxxxxxxxxx" \
-F "type=password-breaches" \
-F "download_link=true" \
-F "file=@hashes.csv"
- Charged 1 credit per unique password.
download_link=truereturns adownload_urlin thebulk.completedwebhook; fetch it with your API key.- Export filters:
all,breached. Only the masked hash prefix and breach count are stored - never the password or full hash.
Cost
1 credit per unique password checked. Repeat single lookups are free during the 6-month free-repeat window.Was this page helpful?