# Password Breach Check API
> Check whether a password has appeared in known data breaches — as an API over Have I Been Pwned's Pwned Passwords corpus (800+ million unique compromised passwords). It uses k-anonymity: only the first 5 characters of a password's SHA-1 hash are ever sent upstream, so the password itself never leaves in full. Pass a password (hashed in memory, never stored or logged — send it via POST so it never appears in a URL/log) or a SHA-1 hash to learn whether it has been breached and how many times; or fetch a raw k-anonymity range for a 5-character hash prefix and do the matching entirely on your own side for zero password exposure. Screening sign-ups and password resets against breached-password lists is recommended by NIST 800-63b, and this makes it a one-call check. A breach / credential-security resource — distinct from password generators, cryptographic hashing and bcrypt. Open data from Have I Been Pwned (Troy Hunt), CC BY 4.0.

## Authentication
All requests require your oanor API key in the `x-oanor-key` header. Get one at https://www.oanor.com/developer/keys.

```bash
curl -H "x-oanor-key: oanor_live_…" "https://api.oanor.com/pwned-api/..."
```

## Pricing
- **Free** (Free) — 2,550 calls/Mo, 2 req/s
- **Starter** ($7/Mo) — 51,000 calls/Mo, 8 req/s
- **Pro** ($23/Mo) — 248,000 calls/Mo, 20 req/s
- **Mega** ($59/Mo) — 880,000 calls/Mo, 50 req/s

## Endpoints

### Pwned Passwords

#### `GET /v1/check` — Is this password in a breach?

**Parameters:**
- `sha1` (query, optional, string) — SHA-1 hash of the password (40 hex) Example: `5BAA61E4C9B93F3F0682250B6CF8331B7EE68FD8`
- `password` (query, optional, string) — The password — prefer POST so it is not logged in a URL

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/pwned-api/v1/check?sha1=5BAA61E4C9B93F3F0682250B6CF8331B7EE68FD8"
```

**Response:**
```json
{
    "data": {
        "sha1": "5BAA61E4C9B93F3F0682250B6CF8331B7EE68FD8",
        "pwned": true,
        "advice": "This password has appeared in known data breaches — do not use it.",
        "breach_count": 52256179
    },
    "meta": {
        "timestamp": "2026-06-01T16:22:52.087Z",
        "request_id": "60624ae4-b0bd-4577-8ffd-7dc64d3422df"
    },
    "status": "ok",
    "message": "Password checked",
    "success": true
}
```

#### `GET /v1/range` — Raw k-anonymity range for a SHA-1 prefix

**Parameters:**
- `prefix` (query, optional, string) — First 5 hex chars of a SHA-1 hash Example: `5BAA6`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/pwned-api/v1/range?prefix=5BAA6"
```

**Response:**
```json
{
    "data": {
        "note": "Match the 35-char suffix of your password's SHA-1 hash against this list; the password's full hash never leaves your side.",
        "count": 1954,
        "prefix": "5BAA6",
        "suffixes": [
            {
                "sha1": "5BAA6003CD215739D7C1B2218670D26F81408237",
                "count": 2,
                "suffix": "003CD215739D7C1B2218670D26F81408237"
            },
            {
                "sha1": "5BAA6003D68EB55068C33ACE09247EE4C639306B",
                "count": 29,
                "suffix": "003D68EB55068C33ACE09247EE4C639306B"
            },
            {
                "sha1": "5BAA600658BFD1E05761042698D19D32CD9F1A8F",
                "count": 15,
                "suffix": "00658BFD1E05761042698D19D32CD9F1A8F"
            },
            {
                "sha1": "5BAA6007AE8281F7E822ECED1706E732E9B5FEEB",
                "count": 1,
                "suffix": "007AE8281F7E822ECED1706E732E9B5FEEB"
            },
            {
                "sha1": "5BAA600C960BB87997DA398D1A0FBFE8043EBB70",
                "count": 2,
                "suffix": "00C960BB87997DA398D1A0FBFE8043EBB70"
            },
            {
                "sha1": "5BAA60110AF224E22E3C1F5FE6C40297C465FFC7",
                "count": 2,
                "suffix": "0110AF224E22E3C1F5FE6C40297C465FFC7"
            },
            {
                "sha1": "5BAA6011E946E4C5B9CD035A5F95845CEC86CD05",
                "count": 2,
                "suffix"
…(truncated, see openapi.json for full schema)
```

### Meta

#### `GET /v1/meta` — Endpoint catalogue, privacy & notes

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/pwned-api/v1/meta"
```

**Response:**
```json
{
    "data": {
        "note": "Pwned Passwords lets you check whether a password has appeared in known data breaches (over 800 million unique breached passwords), so you can block compromised credentials. /v1/check?password=… tells you if a password has been breached and how many times — the password is SHA-1 hashed in memory, only the first 5 hash characters are sent to HIBP (k-anonymity), and the password is never stored or logged; you can instead pass sha1=<40-hex SHA-1> to avoid sending the password at all. /v1/range?prefix=5BAA6 returns the raw k-anonymity range — every breached SHA-1 suffix beginning with that 5-character prefix and its breach count — so you can do the matching entirely on your own side (the recommended zero-exposure flow). Data from Have I Been Pwned (Troy Hunt), CC BY 4.0. A breach / credential-security resource — distinct from password generators, cryptographic hashing and bcrypt. Ideal for sign-up, password-reset and account-security flows (NIST 800-63b breached-password screening).",
        "source": "Have I Been Pwned — Pwned Passwords (api.pwnedpasswords.com)",
        "privacy": "k-anonymity: only the first 5 characters of a SHA-1 hash are ever sent to HIBP. Passwords passed to /v1/check are hashed in memory and never stored or logged; for zero exposure use /v1/range and match client-side.",
        "endpoints": [
            "/v1/check",
            "/v1/range",
            "/v1/meta"
        ]
    },
    "meta": {
        "times
…(truncated, see openapi.json for full schema)
```


---
Marketplace page: https://www.oanor.com/api/pwned-api
OpenAPI spec: https://www.oanor.com/api/pwned-api/openapi.json
