# Fraud Prevention API Integration: From Zero to Protected in 30 Minutes

> A step-by-step guide to integrating Fidro's fraud prevention API. Covers getting your API key, understanding risk scores, integrating into signup and Stripe checkout flows, and tuning your fraud thresholds.

**Author:** Matt King | **Published:** June 24, 2026 | **Category:** Fraud Prevention

---

You know you should be validating emails and checking IPs before processing signups and payments. But between reading docs and figuring out where to put the API call, the integration keeps getting pushed to next sprint.

This guide changes that. In 30 minutes, you will go from zero to a working fraud prevention integration.

## Step 1: Get Your API Key (2 Minutes)

1. Go to [fidro.io/pricing](/pricing) and sign up. The free plan includes 200 requests per month.
2. Copy your API key from the dashboard.
3. Add it to your environment variables:

```bash
# .env
FIDRO_API_KEY=sk_live_your_api_key_here
```

For Laravel:

```php
// config/services.php
'fidro' => [
    'api_key' => env('FIDRO_API_KEY'),
],
```

## Step 2: Make Your First Request (3 Minutes)

```bash
curl -X POST https://api.fidro.io/v1/validate \
  -H "Authorization: Bearer sk_live_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"email": "test@gmail.com", "ip": "8.8.8.8"}'
```

Response:

```json
{
  "risk_score": 32,
  "recommendation": "allow",
  "checks": {
    "datacenter": true,
    "vpn": false,
    "proxy": false,
    "tor": false,
    "disposable_email": false,
    "valid_email": true,
    "location_match": true
  },
  "location": {
    "country_code": "US",
    "city": "Mountain View",
    "isp": "Google LLC"
  }
}
```

Test interactively with the [email checker](/tools/email-checker) and [IP checker](/tools/ip-checker).

## Step 3: Understand the Response (5 Minutes)

### risk_score (0 to 100)

| Score Range | Meaning | Typical Action |
|-------------|---------|----------------|
| 0 to 29 | Low risk | Allow |
| 30 to 69 | Medium risk | Review or add friction |
| 70 to 100 | High risk | Block |

### recommendation

`allow`, `review`, or `block` based on the risk score.

### checks

| Check | What It Means |
|-------|--------------|
| `datacenter` | IP belongs to a cloud/hosting provider |
| `vpn` | IP is a known VPN endpoint |
| `proxy` | IP is an open or residential proxy |
| `tor` | IP is a Tor exit node |
| `disposable_email` | Email uses a throwaway provider |
| `valid_email` | Email domain has valid DNS and MX records |
| `location_match` | IP country matches the provided country_code |

For more, see [what is a risk score and how does it work](/blog/what-is-a-risk-score-and-how-does-it-work).

## Step 4: Integrate into Your Signup Flow (10 Minutes)

Create a service class:

```php
<?php
namespace App\Services;

use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

class FidroService
{
    public function validate(string $email, ?string $ip = null, ?string $countryCode = null): array
    {
        $payload = ['email' => $email];
        if ($ip) $payload['ip'] = $ip;
        if ($countryCode) $payload['country_code'] = $countryCode;

        try {
            $response = Http::timeout(3)
                ->withHeaders(['Authorization' => 'Bearer ' . config('services.fidro.api_key')])
                ->post('https://api.fidro.io/v1/validate', $payload);

            if (! $response->successful()) {
                return $this->failOpenResponse();
            }

            return $response->json();
        } catch (\Exception $e) {
            Log::warning('Fidro API failed', ['error' => $e->getMessage()]);
            return $this->failOpenResponse();
        }
    }

    private function failOpenResponse(): array
    {
        return ['risk_score' => 0, 'recommendation' => 'allow', 'checks' => []];
    }
}
```

Wire it into your registration controller:

```php
public function store(Request $request, FidroService $fidro)
{
    $request->validate([
        'name' => 'required|string|max:255',
        'email' => 'required|email|unique:users',
        'password' => 'required|min:8|confirmed',
    ]);

    $result = $fidro->validate($request->email, $request->ip());

    if ($result['risk_score'] > 70) {
        return back()->withErrors([
            'email' => 'We were unable to process your registration.',
        ]);
    }

    $user = User::create([
        'name' => $request->name,
        'email' => $request->email,
        'password' => Hash::make($request->password),
    ]);

    $user->update([
        'signup_risk_score' => $result['risk_score'],
        'flagged_for_review' => $result['risk_score'] > 30,
    ]);

    Auth::login($user);
    return redirect()->route('dashboard');
}
```

## Step 5: Integrate into Stripe Checkout (10 Minutes)

Call Fidro before creating a PaymentIntent:

```php
public function createPayment(Request $request, FidroService $fidro)
{
    $result = $fidro->validate(
        $request->email,
        $request->ip(),
        $request->billing_country
    );

    if ($result['risk_score'] > 70) {
        return response()->json([
            'error' => 'We could not process this payment.',
        ], 422);
    }

    $stripe = new \Stripe\StripeClient(config('services.stripe.secret'));

    if ($result['risk_score'] > 30) {
        // Medium risk: require 3D Secure
        $paymentIntent = $stripe->paymentIntents->create([
            'amount' => $request->amount,
            'currency' => 'usd',
            'payment_method' => $request->payment_method,
            'confirmation_method' => 'manual',
            'payment_method_options' => [
                'card' => ['request_three_d_secure' => 'any'],
            ],
            'metadata' => [
                'fidro_risk_score' => $result['risk_score'],
            ],
        ]);
    } else {
        $paymentIntent = $stripe->paymentIntents->create([
            'amount' => $request->amount,
            'currency' => 'usd',
            'payment_method' => $request->payment_method,
            'confirm' => true,
            'metadata' => [
                'fidro_risk_score' => $result['risk_score'],
            ],
        ]);
    }

    return response()->json([
        'client_secret' => $paymentIntent->client_secret,
    ]);
}
```

Storing `fidro_risk_score` in Stripe metadata means you can reference it during dispute resolution.

For more Stripe patterns, see [webhook patterns for Stripe fraud prevention](/blog/webhook-patterns-stripe-fraud-prevention).

## Step 6: Tune Your Thresholds

After your first week of live data:

- **Check your block log.** If you are blocking real customers, raise to 80.
- **Check your review queue.** If 80%+ are legitimate, raise review threshold to 40-50.
- **Check your chargebacks.** If they persist from low-score users, lower allow threshold or add custom rules.

For a full guide, see [tuning fraud thresholds](/blog/tuning-fraud-thresholds).

## Common Integration Mistakes

**Failing closed instead of open.** If the API is unavailable and you block all users, you have a denial-of-service vulnerability. Always fail open.

**Blocking on a single signal.** VPN usage alone is not fraud. Use the composite risk score.

**Not logging results.** Without logs, you cannot tune thresholds or build chargeback evidence.

**Skipping the checkout check.** Account takeover means a legitimate account can still be used for fraud. Check at both signup and checkout.

## What You Have Built

After following this guide:

1. **Signup protection** that blocks high-risk registrations and flags medium-risk users
2. **Checkout protection** that prevents fraudulent payments
3. **Logging** for threshold tuning and chargeback evidence

## Testing Tools

- [Email Checker](/tools/email-checker): Test any email for disposable providers and risk
- [IP Checker](/tools/ip-checker): Analyze any IP for VPN, proxy, and datacenter detection
- [VPN Detector](/tools/vpn-detector): Check whether an IP is a VPN endpoint
- [Bulk Email Checker](/tools/bulk-email-checker): Validate email lists in batch
- [Domain Checker](/tools/domain-checker): Check domain reputation

For the full API reference, see the [documentation](/docs). For all capabilities, visit the [features page](/features).

Also check our [email validation API integration guide](/blog/email-validation-api-integration-guide) for email-specific patterns.

---

## Frequently Asked Questions

### How long does it take to integrate Fidro's fraud prevention API?

Most developers have a working integration within 30 minutes. The API accepts a simple JSON payload with an email and/or IP address and returns a risk score with a recommendation. In Laravel or Express, the integration is typically 10-20 lines of code.

### What does the Fidro API response include?

The response includes a risk_score (0 to 100), a recommendation (allow, review, or block), individual check results for VPN, proxy, Tor, datacenter, disposable email, and location match, plus geolocation data.

### Can I integrate Fidro with Stripe checkout?

Yes. Call the Fidro API before creating a Stripe PaymentIntent. If the risk score is above your block threshold, reject the transaction before it reaches Stripe. For medium-risk scores, require 3D Secure.

### What happens if the Fidro API is unavailable?

Always implement a fail-open pattern with a 2-3 second timeout. If the API does not respond in time, allow the action and log the failure. Your flows should never be blocked by API availability.

### Does Fidro offer webhooks?

Yes. Configure webhooks to receive notifications for high-risk activity, usage thresholds, and daily summary reports.

