> ## Documentation Index
> Fetch the complete documentation index at: https://docs.finowl.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Email breach monitoring

> Detect when your users' email addresses appear in new data breaches and prompt them to secure their accounts.

A user whose email appears in a new breach is at risk of credential stuffing, especially if they reused their password. This guide shows how to check users periodically and notify them only about breaches they have not seen before.

## Approach

1. Check each user's email with `POST /v1/breaches/email`.
2. Store the `Name` of every breach you have already seen for that user.
3. On the next check, compare. Any new `Name` is a new breach.
4. Notify the user and suggest a password change.

## Example

```python theme={null}
import os
import time
import requests

session = requests.Session()
session.headers["Authorization"] = f"Bearer {os.environ['FINOWL_API_KEY']}"


def check_user(user):
    response = session.post(
        "https://api.finowl.co/v1/breaches/email",
        json={"email": user.email},
        timeout=40,
    )

    if response.status_code == 429:
        time.sleep(int(response.headers.get("Retry-After", "60")))
        return check_user(user) if response.json()["error"]["code"] == "rate_limited" else None

    response.raise_for_status()
    result = response.json()

    names = {breach["Name"] for breach in result["breaches"]}
    new = names - set(user.known_breaches)

    if new:
        details = [b for b in result["breaches"] if b["Name"] in new]
        notify(user, details)

    user.known_breaches = sorted(names)
    user.save()


for user in users_to_check():
    check_user(user)
    time.sleep(1)  # Stay well under 60 requests per minute.
```

## Picking a schedule

Each check uses 1 credit. Checking 10,000 users once a month uses 10,000 credits a month. Common patterns:

| Strategy | When to check | Credits |
| - | - | - |
| On sign up | Once, when the account is created | 1 per new user |
| On login | At most once every 30 days per user | Scales with active users |
| Scheduled | Monthly, for all active users | 1 per active user per month |

## Writing the notification

A good breach notification:

* Names the breached service using `Title`, and when it happened using `BreachDate`.
* Lists what was exposed using `DataClasses`, such as passwords or phone numbers.
* Recommends a concrete action: change the password on that service and on any site where it was reused, and turn on two-factor authentication.

<Warning>
  `Description` contains HTML. Do not insert it into an email or page without sanitizing it.
</Warning>

<Note>
  `breached: false` means no public breach was found. Sensitive and opted-out breaches are not included, so do not tell users they have "never been breached".
</Note>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.