Skip to content

Password check

Many people reuse passwords, and attackers try passwords from old leaks on new sites. The password check tells you whether a password is in a known leak, so you can ask for another one at signup or at a password change.

It is part of the Pro plan and above.

  1. Your server hashes the password with SHA-1.
  2. It sends only the first 5 hex characters of the hash to POST /v1/password-check.
  3. The service answers with every leaked hash ending that shares the prefix, as lines SUFFIX35:COUNT (35 uppercase hex characters, a colon, a count). Short lists are padded with fake count-0 lines to 800 to 1000 lines, so the size reveals nothing.
  4. Your server compares the rest of the hash locally and ignores lines with count 0.

The service never receives the password or the full hash. The SDKs do all of this for you.

  1. Install a server SDK (Node, Python, PHP, Go, Java).
  2. Call the check where a person chooses a password.
  3. If leaked is true, ask for another one. Do not log the password.
const r = await rg.isPasswordLeaked(password);
if (r.leaked) askForAnotherPassword(); // r.count says how often it was seen

Over plain HTTP:

Terminal window
curl https://api.revokegpt.com/v1/password-check \
-H 'Authorization: Bearer rgsk_...' -H 'Content-Type: application/json' \
-d '{"prefix":"5BAA6"}'

The answer is text/plain with Cache-Control: private, no-store.

Status and code Meaning What to do
400 bad-request The prefix is not exactly 5 hex characters (a full hash is refused). Send 5 characters.
401 unauthorized Bad or missing secret. Check the key.
402 plan-required / plan-restricted Plan too low. See billing.
403 feature-disabled Not enabled for the site. Enable it.
429 rate-limited Too fast. Retry-After: 1. Wait and retry.
503 service-unavailable The range is missing or the feature is off. See below.

A 503 (RevokeGPTUnavailable in the SDK) means “could not check”, never “not leaked”. Decide in advance whether you fail open (let the password through) or closed.

checkCredentialPair(username, password) finds out whether this exact username and password pair was leaked together. It stays off until the platform owner enables it, and while it is off the call throws feature-disabled. It is an RFC 9497 OPRF (ristretto255-SHA512): the credential is blinded on your server, so neither value reaches the service, and the match is made in your process. In an assessment it uses the fields privatePasswordLeakVerification.lookupHashPrefix and encryptedUserCredentialsHash. Usernames are canonicalized; a username with an unassigned code point is refused locally.

  • Request body limit 1 KiB. Never send a full hash or the password to any endpoint.
  • Never show a person the count as a reason to trust or distrust other accounts. Use it only to refuse that password.
  • The check does not replace rate limiting and bot checks on login.