example · laravel

04 / 06

Laravel spam filter.

Updated May 12, 2026

This Laravel example uses the built-in HTTP client to add Siftfy spam detection to a contact route. The closure validates the form, classifies the message via `https://api.siftfy.io/v1/predict`, and dispatches jobs based on the returned probability. It drops only what scores above the response's own `max_confidence`, queues everything from 0.50 up to that ceiling for review, sends leads below — and falls open if the HTTP call throws so a real lead is never lost.

A Laravel controller action using the built-in HTTP client to classify form text before dispatching mail or review jobs.

php
<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Route;

Route::post('/contact', function (Request $request) {
    $data = $request->validate([
        'email' => ['required', 'email'],
        'message' => ['required', 'string'],
    ]);

    $probability = 0.0;
    $ceiling = null;
    try {
        $response = Http::timeout(2)
            ->withHeaders(['X-API-Key' => config('services.siftfy.key')])
            ->post('https://api.siftfy.io/v1/predict', [
                'text' => $data['message'],
            ]);

        if ($response->ok()) {
            $probability = (float) $response->json('spam_probability', 0);
            $ceiling = $response->json('max_confidence');
        }
    } catch (\Throwable $e) {
        $probability = 0.0;
    }

    // Drop only ABOVE the ceiling the response reports. At the ceiling the score
    // is censored, so a fixed constant never fires on the model's own opinion.
    if ($ceiling !== null && $probability > (float) $ceiling) {
        return ['ok' => true];
    }
    if ($probability >= 0.50) {
        QueueContactReview::dispatch($data, $probability);
    } else {
        SendContactLead::dispatch($data);
    }
    return ['ok' => true];
});

Production notes

  1. 01`max_confidence` is the highest score the model is allowed to return on its own word; only a score above it is more than the model's opinion.
  2. 02Put the key in config/services.php and .env, not in source.
  3. 03Dispatch clean and review actions to queues if the downstream CRM is slow.
  4. 04Return success for blocked submissions to avoid training spam senders.

Common questions

How do I add Siftfy spam detection to a Laravel form?

Use `Illuminate\Support\Facades\Http` to POST the message body to `https://api.siftfy.io/v1/predict`, then branch on `spam_probability` in the response. The full route closure is shown above.

Where should the Siftfy API key go in Laravel?

Put it in `.env` as `SIFTFY_KEY=...` and expose it through `config/services.php` as `services.siftfy.key`. Read it inside the route or controller via `config('services.siftfy.key')`.

How do I avoid slowing down Laravel form submissions?

Cap the HTTP timeout at 2 seconds and dispatch the downstream lead-delivery work to a queue (Redis, SQS, or database) so the API call returns immediately even when the CRM is slow.

Should I show a Laravel error when spam is detected?

No. Return the same success payload for spam and clean submissions. Surfacing a spam-specific error to the user trains spammers and offers no benefit to legitimate visitors.

Get a free API key

More patterns: all examples, contact forms, API reference.