TypeScript · Email breach checks
Check email breaches in TypeScript with typed results
The email breach response has two levels: a lowercase envelope with email, breached and breaches, and PascalCase breach records with fields such as Title, BreachDate, DataClasses and IsVerified. Writing those as TypeScript types means your editor autocompletes the right casing and the compiler flags any mismatch, which is handy when the same data feeds an API response, a React email template and a database model.
The example declares only the fields it uses plus a few flags, which keeps the type honest without copying every property. Error handling is done with a small typed retry loop: 400 and 401 throw immediately, a rate_limited 429 waits for Retry-After, and anything else surfaces with its code. Swap the console output for your own notification or audit logic once it compiles.
Steps
- 1
Install typescript, tsx and @types/node as dev dependencies.
- 2
Add the Breach and EmailBreachResult types to a shared module in your project.
- 3
Export FINOWL_API_KEY and run npx tsx check-email.ts alex@example.com.
- 4
Use the typed result to decide which DataClasses warrant a password reset prompt.
npm install --save-dev typescript tsx @types/node// check-email.ts (run with: npx tsx check-email.ts alex@example.com)
type Breach = {
Name: string;
Title: string;
Domain: string;
BreachDate: string;
DataClasses: string[];
IsVerified: boolean;
IsSensitive: boolean;
};
type EmailBreachResult = { email: string; breached: boolean; breaches: Breach[] };
type ErrorBody = { error?: { code?: string } };
const sleep = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms));
async function checkEmail(email: string, attempts = 3): Promise<EmailBreachResult> {
for (let i = 0; i < attempts; i++) {
const res = await fetch("https://api.finowl.co/v1/breaches/email", {
method: "POST",
headers: {
Authorization: "Bearer " + process.env.FINOWL_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({ email }),
signal: AbortSignal.timeout(10_000),
});
if (res.ok) return (await res.json()) as EmailBreachResult;
const code = ((await res.json().catch(() => ({}))) as ErrorBody).error?.code ?? "unknown_error";
if (res.status === 400) throw new Error("Invalid email address (" + code + ")");
if (res.status === 401) throw new Error("Unauthorized: check FINOWL_API_KEY");
if (res.status === 429 && code === "rate_limited") {
await sleep((Number(res.headers.get("retry-after")) || 1) * 1000);
continue;
}
throw new Error("Finowl error " + res.status + ": " + code);
}
throw new Error("Still rate limited after " + attempts + " attempts");
}
async function main(): Promise<void> {
const result = await checkEmail(process.argv[2] ?? "alex@example.com");
if (!result.breached) {
console.log(result.email + " does not appear in any known breach");
return;
}
for (const breach of result.breaches) {
const flag = breach.IsVerified ? "" : " [unverified]";
console.log(breach.Title + " (" + breach.BreachDate + ")" + flag);
console.log(" exposed: " + breach.DataClasses.join(", "));
}
}
main().catch((err: unknown) => {
console.error(err instanceof Error ? err.message : err);
process.exitCode = 1;
});IN PRODUCTION
Production tips
Treat the JSON cast as a trust boundary. If you want runtime guarantees, validate the response with a schema library such as zod before passing breach data deeper into your app.
Type BreachDate as a string and parse it deliberately. It is a calendar date like 2019-03-01, while AddedDate is a full ISO timestamp, so do not mix the two in comparisons.
Keep the result types in one shared package if you have several services. That way a frontend, a worker and an API route all agree on the PascalCase field names.
Each lookup costs 1 credit, with 100 free credits every month. See pricing and error codes.
A FEW GOOD QUESTIONS
Common questions
Related guides
- Check breached passwords in TypeScript
- Batch gender prediction in TypeScript
- Check email breaches in Python with requests
- Check email breaches in Node.js with fetch
- Check email breaches in Go with net/http
- Check email breaches in Java with HttpClient
- Email breach checks for fintech signups and logins
- Email breach checks for online stores and shopper logins
- Email breach checks for SaaS logins and admins
Check email breaches in TypeScript with typed results
Grab an API key, paste the example and run it. 100 free credits every month.