AbuseGraph + NextAuth
Check Auth.js signup and sign-in events with the HTTPS API and optional browser signals.
Quick path
- Copy a test key from the console; no package installation is required for the browser or HTTPS API path.
- Collect browser signals on auth forms →
toCheckBody→ send to your server route. - Use
callbacks.signInto gate login; check signup in your account-creation handler.
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_… / pk_live_… in production after DNS verify.
Server check
Call the HTTPS API from your server. Keep ABUSEGRAPH_SECRET_KEY in server-only environment configuration. Events: signup | login | password_reset | email_change; sessionId is optional.
const API = "https://abusegraph.com/api/v1/check";
export async function scoreAuth(input: Record<string, unknown>) {
const site = process.env.ABUSEGRAPH_SITE!;
const response = await fetch(API, {
method: "POST",
headers: {
"content-type": "application/json",
"x-api-key": process.env.ABUSEGRAPH_SECRET_KEY!,
"x-abusegraph-site": site,
},
body: JSON.stringify({
...input,
event: typeof input.event === "string" ? input.event : "signup",
site,
}),
});
if (!response.ok) throw new Error(`AbuseGraph check failed: ${response.status}`);
return response.json();
}Run this before creating an account or issuing a session. Handle block and challenge according to your policy; 402 means the live monthly allowance is exhausted.
Browser signals (recommended)
Load the browser SDK from the AbuseGraph CDN before your signup/login code. The publishable key is safe to expose; send the resulting body to your own backend, which makes the authoritative check with its server-held secret key.
<script src="https://abusegraph.com/sdk/abusegraph.min.js"></script>
<script>
const sdk = AbuseGraph.init({ publicKey: "pk_test_…" });
async function collectForAuth(email, event = "signup") {
const collected = await sdk.collect();
const evaluated = await sdk.evaluate(collected, { email });
return sdk.toCheckBody(collected, {
email,
event,
verdictToken: evaluated.verdictToken?.token,
});
}
</script>POST the returned JSON to your own endpoint. Never treat the browser result as the authoritative decision or put an sk_ key in browser code.
Auth.js / NextAuth callbacks
Use callbacks.signIn to block before Auth.js issues a session. Auth.js events run after the auth action and are suitable for monitoring, not enforcement. Check signup in your account-creation handler before creating the user.
// auth.ts
export const authConfig = {
callbacks: {
async signIn({ user }) {
if (!user.email) return false
const result = await scoreAuth({
email: user.email,
userId: user.id,
event: "login",
})
return result.verdict !== "block"
},
},
}Lifecycle events
- login —
callbacks.signInwithevent: "login"; useevents.signInonly for monitoring. - password_reset — call check in your reset route with
event: "password_reset". - email_change — call before applying the 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
Sign up once with sk_test_…, then open Activity. Blocked users should not retain a session.