BYTETOOLS

Pwned Passwords API

Free Have I Been Pwned password API with no key. Check if a password appears in known breaches using k-anonymity — the password never leaves your server. Tested.

No API key requiredCORS enabledHTTPSFree tier

Endpoint tested and returned HTTP 200 on 2026-08-19

What is the Pwned Passwords API?

The Pwned Passwords API lets you check whether a password has appeared in a known data breach without ever sending the password. It uses k-anonymity: you send only the first five characters of its SHA-1 hash, and it returns all matching suffixes.

This is the best-designed free security API in existence, and the design is the point. You never transmit the password, or even its full hash. You SHA-1 the password locally, send the first five hex characters, and receive back every hash suffix in that bucket along with how many times each appeared in a breach.

You then match the remainder of your hash locally. The server learns nothing about which password you were checking — it saw one of roughly a million buckets. This is exactly how NIST recommends screening passwords against known breaches, and it needs no API key at all.

Quick facts

Base URL
https://api.pwnedpasswords.com
Authentication
No API key required for the Pwned Passwords range endpoint. Other HIBP endpoints do require a paid key.
Rate limit
No rate limit on the range endpoint — it is designed to be called on every password set.
Pricing
Free, including commercial use.
CORS
Enabled — callable directly from browser JavaScript
Official docs
Read the docs

How to use the Pwned Passwords API

Every request below was executed against the live API on 2026-08-19, and the response shown is the real body it returned — not an illustration.

1. Check a hash prefix range

GET https://api.pwnedpasswords.com/range/21BD1

curl
curl 'https://api.pwnedpasswords.com/range/21BD1'
JavaScript (fetch)
const res = await fetch("https://api.pwnedpasswords.com/range/21BD1");
if (!res.ok) throw new Error(`Request failed: ${res.status}`);
const data = await res.json();
console.log(data);
Python (requests)
import requests

res = requests.get("https://api.pwnedpasswords.com/range/21BD1", timeout=20)
res.raise_for_status()
print(res.json())
Response — HTTP 200
0002EEFFB2CCA91812B5CC9956854E22BEB:4
000F6468C6E4D09C0C239A4C2769501B3DD:5959
00115AE168591C338025516216655E42A09:17
0018A45C4D1DEF81644B54AB7F969B88D65:9
0067AD792FB5BA36BECEF3506EE21E41DD9:59
009F8BAECE04D85D02A358D8BAF99819D2F:10
00BF5B8932DFD00FDB4A9529E7923068928:4
00CF63A94500831584A7BBAB1CCF86CBE17:70
00D4F6E8FA6EECAD2A3AA415EEC418D38EC:3
011053FD0102E94D6AE2F8B83D76FAF94F6:1
012

Parameters

ParameterTypeRequiredDescription
<prefix>pathRequiredFirst 5 characters of the password's uppercase SHA-1 hash. 21BD1
Add-PaddingheaderOptionalSet to true to pad responses so their size leaks nothing. true

Response fields

(plain text)text
Line-separated `HASHSUFFIX:COUNT` pairs. Not JSON — parse by splitting on newlines and colons.
COUNTinteger
How many times that password appeared across known breaches. Higher means more dangerous.

What you can build with the Pwned Passwords API

  • Reject known-breached passwords at signup or password change
  • Audit existing password hashes against breach corpora
  • Meet NIST 800-63B guidance on screening compromised credentials
  • Teach k-anonymity as a practical privacy-preserving technique

Common errors and how to fix them

400

Prefix is not exactly 5 hexadecimal characters.

Fix: Uppercase the SHA-1 hash and take exactly the first 5 characters.

No match found in the response

The password does not appear in any known breach — this is the good case.

Fix: Absence from the list is not proof a password is strong; still enforce length and complexity rules.

Response is not JSON

It is plain text by design.

Fix: Split on newlines, then on ':' to get suffix and count.

Pwned Passwords API — frequently asked questions

Is it safe to send passwords to this API?

You never send the password or its full hash. You send only the first five characters of the SHA-1 hash and match the rest locally — the server cannot tell which password you checked. That is the k-anonymity model.

Does the Pwned Passwords API need an API key?

No. The range endpoint is completely free and unauthenticated, deliberately, so that everyone can screen passwords. Other Have I Been Pwned endpoints do require a paid key.

What does the count number mean?

How many times that password appeared across all known breaches. A count in the millions means it is one of the most commonly used passwords in existence and should always be rejected.

Should I block any password that appears at all?

Common practice is to reject anything appearing more than a handful of times. Blocking every single hit is defensible but will frustrate users with otherwise strong passphrases that leaked once.

Tools that pair with this API

Pwned Passwords is an independent third-party service and is not affiliated with ByteTools or ByteVancer. Details on this page were verified on 2026-08-19; always check the official documentation before relying on this API in production, as terms and limits can change.