Skip to main content
POST
Password Breaches

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 three ways to run it:
  • Agent API (POST /api/agent/password-breaches): the API-key endpoint documented on this page, for programmatic access (e.g. your sign-up backend).
  • In-app (POST /api/password/breaches): the session-authenticated endpoint used by the dashboard, where the browser hashes the password first.
  • Bulk (POST /api/password/breaches/bulk): check up to 1,000 passwords in one request.
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

string
The raw password to check. Hashed server-side (SHA-1) immediately and never stored; only the 5-char hash prefix leaves the server.
For production, prefer sending a pre-computed hash instead of the raw password: pass sha1 (upper-case hex SHA-1 of the password) in place of password, so the plaintext never leaves the caller. Provide exactly one of password or sha1.

Response

Bulk

POST /api/password/breaches/bulk accepts sha1s (array of hashes) or passwords (array of raw passwords), up to 1,000 entries, and charges 1 credit per unique password:

Cost

1 credit per password checked (single and per-password in bulk).

Enterprise / async bulk (up to 1M)

For large lists (banks, enterprises), use the async job pipeline instead of the synchronous bulk endpoint. The browser SHA-1 hashes every password first, so the uploaded input is a list of hashes, and plaintext never reaches the server.
  • POST /api/password-jobs: body { "sha1s": ["<40-hex>", ...], "file_name": "list.txt" } (up to 1,000,000). Returns a job { id, status, total, ... }.
  • GET /api/password-jobs?id=<id>: poll live status + counts (processed_count, breached_count).
  • GET /api/password-jobs/results?id=<id>&page=&page_size=&breached=1: paginated result rows ({ line_no, prefix, found, count }).
  • GET /api/password-jobs/download?id=<id>&breached=1: stream the full results as CSV.
  • POST /api/password-jobs/cancel?id=<id>: cancel an in-flight job.
Jobs are processed by background workers in resumable chunks, so a 1M-row job runs reliably without a long-held HTTP request. 1 credit is charged per password.