The highest-leverage place to add Fidro is your signup form. Validating users at registration means you catch bad actors before they ever get access to your product.
How it works
When a user submits your registration form, you call the Fidro API with their email and IP address. Based on the risk score, you can allow, flag, or block the signup.
Server-side implementation
Always call Fidro from your backend — never from the browser. This protects your API key and prevents users from bypassing the check.
Laravel
// In your registration controller or action
$response = Http::withToken(config('services.fidro.api_key'))
->post('https://api.fidro.io/api/validate', [
'email' => $request->input('email'),
'ip' => $request->ip(),
]);
$result = $response->json();
if ($result['risk_score'] >= 71) {
// Block the signup
return back()->withErrors([
'email' => 'We were unable to verify your identity. Please contact support.',
]);
}
if ($result['risk_score'] >= 41) {
// Allow but flag for review
$user = User::create([...]);
$user->update(['flagged_for_review' => true]);
} else {
// Clean signup — proceed normally
$user = User::create([...]);
}
Next.js (API Route)
// app/api/register/route.ts
import { NextResponse } from 'next/server';
export async function POST(request: Request) {
const body = await request.json();
const ip = request.headers.get('x-forwarded-for') || '127.0.0.1';
const fidroResponse = await fetch('https://api.fidro.io/api/validate', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.FIDRO_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ email: body.email, ip }),
});
const risk = await fidroResponse.json();
if (risk.risk_score >= 71) {
return NextResponse.json(
{ error: 'Unable to verify your identity.' },
{ status: 422 }
);
}
// Proceed with user creation...
}
Express
app.post('/register', async (req, res) => {
const { email } = req.body;
const ip = req.headers['x-forwarded-for'] || req.socket.remoteAddress;
const response = await fetch('https://api.fidro.io/api/validate', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.FIDRO_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ email, ip }),
});
const risk = await response.json();
if (risk.risk_score >= 71) {
return res.status(422).json({ error: 'Signup blocked.' });
}
// Create user...
});
Choosing your threshold
The default thresholds work well for most products:
| Score | Default action | Good for |
|---|---|---|
| 0–40 | Allow | Most signups will fall here |
| 41–70 | Review | Send to a moderation queue |
| 71–100 | Block | Reject at signup |
You can adjust these based on your risk tolerance. A marketplace might block at 60, while a free tool might only block at 85.
What to show the user
Don't reveal that you're checking for fraud. Generic error messages work best:
- Good: "We weren't able to verify your information. Please try again or contact support."
- Bad: "Your email was flagged as disposable" (tells fraudsters exactly what to change)
Handling edge cases
- No IP available? Send just the email — Fidro will score based on email signals alone.
- Country mismatch? Pass
country_codeif you know the user's expected country for geo-mismatch detection. - API timeout? Set a 3-second timeout and fall back to allowing the signup. It's better to let one bad actor through than block a real customer.