# Add Fidro to Your Signup Form

> Validate emails and IPs at registration to block fraud before it starts.

**Category:** getting-started | **Last updated:** March 13, 2026

---

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

```php
// 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)

```typescript
// 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

```javascript
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_code` if 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.