Skip to content

Fraud & Suspicion Detection

Every lead is assigned a suspicion score (0-100) based on multiple signals that indicate bot activity, competitor scraping, or spam submissions.

Suspicion Signals

SignalPointsTrigger
Honeypot filled+40Invisible field has a value (bots fill all fields)
Fast submit (<5s)+30Form submitted in under 5 seconds (inhuman speed)
Quick submit (5-10s)+10Form submitted between 5-10 seconds (suspicious)
No tracking session+15No visitor session found for this visitor_id or IP
Zero engagement+10Tracking session exists but engagement score is 0
VPN suspected (high)+15VPN suspicion score > 50
VPN suspected (moderate)+5VPN suspicion score > 20
High form velocity (3+ in 24h)+203 or more form submissions from same visitor in 24 hours
Moderate form velocity (2 in 24h)+102 form submissions from same visitor in 24 hours
Competitor email domain+25Email from a known competitor domain

Maximum possible score: 100 (signals are additive but capped)

How It Works

Honeypot Field

The form builder (/form.js) injects an invisible field named __pg_website that is:

  • Positioned off-screen (left: -9999px)
  • Hidden with aria-hidden="true"
  • Has tabindex="-1" and autocomplete="off"

Real users never see or fill this field. Automated bots that fill all fields will trigger a +40 suspicion score.

Time-to-Submit

The form records Date.now() when the form renders and calculates the elapsed seconds when the user submits. This is sent as __pg_tts.

  • Under 5 seconds: +30 (bot speed — no human reads a form this fast)
  • 5-10 seconds: +10 (suspicious — most real users take 15-30 seconds)

Multi-Form Tracking

countRecentSubmissions() queries the Leads table for submissions by the same VisitorId or ContactIP within the last 24 hours. The count is stored as FormSubmitCount on each lead.

  • 2 submissions in 24h: +10
  • 3+ submissions in 24h: +20

Note: Multiple submissions can be legitimate when a visitor inquires about multiple projects on the same page.

Competitor Email Detection

The system checks the email domain against a configurable list of known competitor domains. Leads from competitor emails receive +25 suspicion.

Data Stored

ColumnTypeDescription
SuspicionScoreREALComposite score 0-100
SuspicionReasonsTEXTComma-separated list of triggered signals
TimeToSubmitINTEGERSeconds between form render and submit
FormSubmitCountINTEGERNumber of submissions by this visitor in 24h (including current)

Usage in CRM

The suspicion score is included in the webhook payload to Make.com:

json
{
  "suspicion_score": 55,
  "suspicion_reasons": "fast_submit,no_tracking_session,form_velocity_high",
  "time_to_submit": 3,
  "form_submit_count": 4
}

Sales teams can use this to:

  • Auto-archive leads with suspicion > 70
  • Flag for review leads with suspicion 30-70
  • Prioritize leads with suspicion 0 + high engagement score

D1 Schema (Migration 006)

sql
ALTER TABLE Leads ADD COLUMN FormSubmitCount INTEGER DEFAULT 1;
ALTER TABLE Leads ADD COLUMN SuspicionScore REAL DEFAULT 0;
ALTER TABLE Leads ADD COLUMN SuspicionReasons TEXT;
ALTER TABLE Leads ADD COLUMN TimeToSubmit INTEGER DEFAULT 0;