Password Breaches
curl --request POST \
--url https://developer.encrata.com/api/lookup/email/password/breaches \
--header 'Authorization: Bearer <token>' \
--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": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', '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: Bearer <token>",
"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", "Bearer <token>")
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", "Bearer <token>")
.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"] = 'Bearer <token>'
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,
"credits": 1,
"credits_charged": 1,
"cache_hit": false
}
{ "error": "no credits" }
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: Bearer <token>' \
--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": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', '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: Bearer <token>",
"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", "Bearer <token>")
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", "Bearer <token>")
.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"] = 'Bearer <token>'
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,
"credits": 1,
"credits_charged": 1,
"cache_hit": false
}
{ "error": "no credits" }
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:- Agent API (
POST /api/lookup/email/password/breaches): the API-key endpoint documented on this page, for programmatic access (e.g. your sign-up backend). - Async jobs (
POST /api/jobs/password): up to 1,000,000 passwords processed in the background.
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.
Request
Provide exactly one ofsha1 (recommended) or password.
string
Upper-case hex SHA-1 of the password (40 hex chars). 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 $ENCRATA_API_KEY" \
-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.
number
Credits charged for this request (always
1).number
Duplicate of
credits, included for usage tracking.boolean
Always
false; password checks are not cached.Errors
Errors return a JSON body of the form{"error": "<message>"} with the matching
HTTP status code.
| Status | Message | Cause |
|---|---|---|
400 | bad body | Malformed JSON |
400 | provide sha1 or password | Neither sha1 nor password supplied |
401 | bad key | Missing or invalid API key |
402 | no credits | No credits remaining |
405 | POST only | Wrong HTTP method |
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,
"credits": 1,
"credits_charged": 1,
"cache_hit": false
}
{ "error": "no credits" }
Bulk (asynchronous)
To check a whole list, submit it as an async job instead of looping this endpoint. SHA-1 hash every password client-side first, so plaintext never reaches the server. One entrypoint handles every lookup - settype=password-breaches -
and a webhook delivers the finished file when it’s done.
curl -X POST "https://developer.encrata.com/api/jobs/bulk" \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "type=password-breaches" \
-F "download_link=true" \
-F "file=@hashes.csv"
- Up to 1,000,000 SHA-1 hashes per job, 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 (single and async job). Duplicate passwords are de-duplicated and only charged once.Was this page helpful?