check

Breach exposure of a password, checked as an indicator.

Changed on

Send the SHA-1 or NTLM of the password — never the password itself, which is refused with a 400. The answer comes from the local copy of Have I Been Pwned's Pwned Passwords corpus (~2 billion hashes per mode, refreshed monthly); nothing is cached, stored or saved as a report. For k-anonymity, where only 5 hex digits leave your side, use GET /pwned-passwords/range/{prefix} instead. One request of the monthly quota.

post/check/password

Request

  • Base URL
    https://api.ismalicious.com
  • Auth
    • API key in header X-API-KEY
    • or HTTP bearer
    • or HTTP basic

Request body

hashstring nullable

Either digest; 40 hex reads as SHA-1, 32 as NTLM

ntlmstring nullable

NTLM hash of the password (MD4 of its UTF-16LE form), 32 hex characters

sha1string nullable

SHA-1 of the password, 40 hex characters

Example request

{
  "ntlm": "8846F7EAEE8FB117AD06BDD830B7586C",
  "sha1": "5BAA61E4C9B93F3F0682250B6CF8331B7EE68FD8"
}

Response

Verdict for the password behind the digest

apiVersionstring required
corpusUpdatedAtstring nullable

When the local copy of the corpus was downloaded

countinteger required

Times the password appears in the breach corpus

exposedboolean required

Seen at least once in a breach

hashTypestring required

sha1 | ntlm

indicatorTypestring required

Always password

prevalencestring required

none | rare (1–9) | common (10–999) | very_common (1 000+)

recommendationstring required

One sentence to relay to the user

sourcestring required
sourceUrlstring required
verdictstring required

compromised | not_found. Not found says nothing about strength

Example response

{
  "apiVersion": "v2",
  "count": 52372427,
  "hashType": "sha1",
  "indicatorType": "password",
  "prevalence": "very_common",
  "source": "Have I Been Pwned — Pwned Passwords",
  "sourceUrl": "https://haveibeenpwned.com/Passwords",
  "verdict": "compromised"
}

Changes