AbuseGraph + Express
Express middleware with createCheckClient — score signup and login before issuing a session.
Quick path
- Set
ABUSEGRAPH_SECRET_KEYandABUSEGRAPH_SITEin env. - Install
@abusegraph/server(and@abusegraph/sdkif you have a browser client). - Add middleware on register/login routes that calls
createCheckClient.check.
Keys
| Key | Env | Use |
|---|---|---|
| Secret | ABUSEGRAPH_SECRET_KEY (sk_test_… / sk_live_…) | Server /api/v1/check |
| Publishable | NEXT_PUBLIC_ABUSEGRAPH_PUBLISHABLE_KEY (pk_test_…) | Browser SDK |
| Site | ABUSEGRAPH_SITE | DNS-verified domain |
Free includes 1,000 live API checks / month after DNS verify. Test keys never bill.
Env
ABUSEGRAPH_SITE=yourdomain.com
ABUSEGRAPH_CHECK_URL=https://abusegraph.com/api/v1/check
ABUSEGRAPH_SECRET_KEY=sk_test_…
ABUSEGRAPH_SECRET_KEY_TEST=sk_test_…
NEXT_PUBLIC_ABUSEGRAPH_PUBLISHABLE_KEY=pk_test_…Use sk_live_… in production after DNS verify.
Server check
Use @abusegraph/server createCheckClient. Events: signup | login | password_reset | email_change. Optional sessionId.
import { createCheckClient } from "@abusegraph/server"
const abusegraph = createCheckClient({
secretKey:
process.env.NODE_ENV === "production"
? process.env.ABUSEGRAPH_SECRET_KEY! // sk_live_…
: process.env.ABUSEGRAPH_SECRET_KEY_TEST ??
process.env.ABUSEGRAPH_SECRET_KEY!, // sk_test_…
site: process.env.ABUSEGRAPH_SITE!,
})Browser signals (recommended)
If you serve a web UI, use init + collect + evaluate + toCheckBody — NEVER bare sdk.check() alone as the authoritative decision. POST browserFields with your register/login request body.
Express middleware
import type { Request, Response, NextFunction } from "express"
import { createCheckClient } from "@abusegraph/server"
const abusegraph = createCheckClient({
secretKey: process.env.ABUSEGRAPH_SECRET_KEY!,
site: process.env.ABUSEGRAPH_SITE!,
})
export function abusegraphGuard(event: "signup" | "login") {
return async (req: Request, res: Response, next: NextFunction) => {
const email = req.body?.email
if (!email) return next()
const { password, ...browserFields } = req.body
const result = await abusegraph.check({
email,
event,
ip: req.ip,
...browserFields,
})
if (result.verdict === "block") {
return res.status(403).json({ error: "blocked", ...result })
}
if (result.verdict === "challenge") {
// require step-up before session create
}
res.locals.abusegraph = result
next()
}
}
app.post("/register", abusegraphGuard("signup"), createUserHandler)
app.post("/login", abusegraphGuard("login"), loginHandler)Lifecycle events
- login —
abusegraphGuard("login")before session create. - password_reset — middleware or route handler with
event: "password_reset". - email_change — call check after email update with
event: "email_change".
Platform
Lists, rules, and linked accounts apply on every check — configure in the console. Optional session: POST /api/v1/session. Native apps: iOS, Android, React Native.
Verify
POST to /register with sk_test_…, confirm Activity shows the check, and blocked emails get 403.