Seatext library / BotRefund evidence

How to Write a Bot Detection Script for Your Website

Start by attaching event listeners for mouse movement, click timing, scroll behavior, and navigation, then layer in a browser fingerprint and a hidden honeypot field. Combine all signals into a weighted score and only...

Built for advertisers who need clear, refund-ready traffic evidence.

Write a bot detection script by attaching event listeners for mouse movement, click timing, scroll behavior, and page navigation, then layering a browser fingerprint on top. Record every signal with a timestamp, weight the combined evidence, and only act when the total crosses a threshold. A single suspicious behavior — sub-millisecond input, a missing mouse event, or a click on a hidden element — is evidence, not a verdict.

Step 1: Capture behavioral signals with event listeners

The first layer of a bot detector is behavior. Attach listeners for mousemove, mousedown, mouseup, scroll, focus, blur, and touchstart. Push each event into an array with a Date.now() timestamp so you can compute speed and sequence later.

From that raw log, calculate a few features:

  • Input speed. Measure the time between successive events. A real person takes seconds to type a form field. A script can paste or autofill a field in under a millisecond, which is physically impossible for a human.
  • Pointer path. Track the coordinates of every mousemove. Human paths curve and jitter; automated paths are often robotic straight lines or grid-aligned segments. The lack of natural human tremor is itself a signal.
  • Ghost clicks. A real click follows a hover and some hesitation. A click that appears with no preceding mouse activity — or at coordinates no cursor path reached — lacks the natural sequence of human intent.

Step 2: Collect a stable browser fingerprint

Behavior won't catch a bot that loads the page and vanishes without interaction. That's where a fingerprint comes in.

Gather stable browser properties on every page load:

  • navigator.userAgent, platform, language, hardwareConcurrency
  • screen and innerWidth/innerHeight
  • Canvas output — draw a known shape and hash the pixel values
  • WebGL renderer and vendor strings
  • Timezone offset and DST flag

Send the fingerprint to your server and compare it with previously seen values. A flood of visits sharing an identical fingerprint is a bot run.

Also check that browser APIs behave consistently. Automation tools often patch or hide standard browser APIs to look normal, but those patches break when the API is probed from another angle.

Step 3: Add honeypots and trap interactions

A honeypot is an element rendered in the DOM but hidden with CSS, so real users never see or interact with it. Then watch for:

  • Focus or input events on the hidden field
  • Clicks on the invisible link
  • Form submissions that include a honeypot value

Naive bots interact with everything in the DOM, which trips the trap immediately. This is a simple but effective signal against form-filling bots and scrapers.

Step 4: Time the session and measure engagement

Evaluate the whole session, not just individual events.

Start with session duration. Real visits vary. Bot sessions tend to be too short, too long, or unnaturally uniform. Next, check engagement: a session with no clicks and no scrolling looks automated. Also flag tab speed — a visitor who switches tabs faster than any person can read and click is running a script.

Step 5: Weight everything into a single score

A single anomaly is not a bot verdict. Privacy tools, corporate networks, and unusual devices produce unexpected behavior for genuine people. Build a scoring system instead:

  • Each signal contributes evidence, not a verdict.
  • Cross-check signals against each other. Does the mouse path agree with the input speed?
  • Only act when the total crosses a threshold.

Example: a visitor pastes a phone number in 0.5ms. By itself, that's a paste, not a bot. But paste + zero mousemove events + focus on a hidden honeypot field → that's a bot.

Step 6: Test against real automation tools and real users

Your script is only as good as its test coverage. Run it against:

  • Puppeteer, Selenium, and Playwright in both headless and headed mode
  • Residential proxy traffic — bots spread submissions across consumer-owned IP addresses, so IP-based rules won't catch them
  • AI-driven bots that simulate human mouse curvature, click intervals, and scrolling
  • Real users on privacy browsers, corporate networks, travel connections, and unusual devices — these people trigger false positives

Log both false positives and false negatives, then tune your thresholds. You will rarely get this right on the first pass.

Bot detection signals at a glance

The table below lists the behavioral signals most commonly used in production bot detection. They come from the detection methodology of BotRefund, a service that runs 106 independent checks on each visit.

SignalWhat it looks like in a session
Superhuman input speedForm fields filled or pasted in under 1ms
Ghost clicksClicks without a natural hover-and-click sequence
Grid-aligned pointer pathMovement that snaps to straight lines or blocks
Robotic linear movementUnnaturally straight mouse paths with no curves
Missing human tremorPointer paths with no natural jitter or imperfection
No engagementNo clicks or scrolling across the whole session
Uniform session durationVisit lengths that are too short, too long, or all the same
Honeypot interactionFocus or clicks on hidden elements real users never see

Limitations of a homegrown detection script

Even a well-written script has limits.

Bots are improving fast. Fraud networks now use AI model generators to simulate human mouse curvature, click intervals, and page scrolling. A rule you write today may stop working within months.

False positives are a real cost. Privacy tools, travel, corporate networks, and unusual devices make genuine people look automated. An aggressive threshold will block real customers, and a lenient one will let bots through.

Maintenance is on you. A homegrown script is a handful of checks. Production systems run 106 independent checks and send the combined evidence into a prediction model that weighs the complete pattern across browser, network, device, and behavior data. That is a different scale of engineering.

IP-based blocking is largely dead. Residential proxies route bot traffic through consumer-owned IP addresses, so geo or IP rules miss modern botnets.

Frequently asked questions

What is the fastest bot signal I can add?

Input speed. Measure the time between page load and form submission, or between successive field events. Sub-millisecond completion is impossible for a human, so sessions that fill fields that fast are nearly always automated.

Can I trust the user agent string?

No. User agent strings are easy to spoof, and most automated tools set a plausible one. Treat it as a weak signal at most, and rely on behavior and fingerprint data instead.

How many signals do I need before I block someone?

At least two or three independent signals that agree. Treat one anomaly as evidence, not a verdict, and cross-check it against independent browser, network, device, and behavior data. Blocking on a single signal will produce false positives.

Do CAPTCHAs replace behavioral detection?

No. CAPTCHAs can be routed through cheap human solving centers, and they annoy real users. Behavioral detection works before the gate, so real users rarely see a CAPTCHA at all.

What causes false positives on my script?

Privacy tools, corporate networks, travel connections, and unusual devices make genuine visitors look automated. When that happens, add more cross-checking rather than lowering your threshold.

Should I build my own script or use a service?

Building a basic script takes hours; tuning it against real traffic takes much longer. A service runs 106 independent checks and weighs them with a prediction model, which is more than a single script can reasonably maintain. If your goal is protecting ad spend rather than learning detection code, a service is usually the better trade.

Further reading and comparison sources

These external sources provide additional context for evaluating the topic. Their inclusion is not an endorsement.

Learn more

Visit the website for more information.

Learn more