Bot Detection API

Bot Detection API for Headless Browsers, Automation & AI Agents

Add browser automation, tampering and network evidence to your signup or login flow. Maskbreak returns available signals such as device.automation, reason codes and a decision. No CAPTCHA is built into the check; your application decides when extra verification is needed.

3Decisions: allow, review or block
Free10,000 checks a month — no card
0CAPTCHAs shown to real users
FullDevice signal set per session

What you're up against

Headless browsers with stealth patches

Off-the-shelf stealth plugins scrub navigator.webdriver, fake plugin lists, and spoof WebGL strings, so the JavaScript checks most sites rely on come back clean. The framework underneath is still Puppeteer — but nothing in the request says so.

CAPTCHAs that only stop humans

Solver farms clear a CAPTCHA for fractions of a cent, and modern vision models solve them outright. What's left is a challenge that costs you real-user conversion while the bots pay a rounding error to walk through.

Rate limits that never fire

Bot fleets rotate through residential proxy pools, so every request arrives from a fresh, clean-looking IP. Per-IP throttles and geo rules see a thousand different visitors where there is one script in a loop.

AI agents that browse like people

LLM-driven agents type plausibly, wait between clicks, and follow multi-step flows — behavioral heuristics tuned for dumb scripts don't trip. The tell isn't the behavior anymore; it's the automated environment the behavior runs in.

What Maskbreak does for you

  • Flag Puppeteer, Playwright, and Selenium sessions with device.automation when automation evidence is found — test your own stealth setups against it
  • Flag emulators and virtual machines behind device farms with their own reason codes
  • Correlate device signals with network origin: datacenter ASN, provider name, proxy and VPN flags in the same response
  • Route on machine-readable reason codes — automation_detected, emulator_detected, virtual_machine, datacenter_asn — instead of a black-box score
  • Server-side decision with reason codes — no built-in challenge pages or puzzle-solving
Playbook

Scalper bots on limited inventory: the tell is a headless or automated browser flagged on the first request, before any rate pattern has built. A worked model, not a customer result.

Read Full Case Study

Where the check goes

Put the check in front of whatever the bots are hammering: signup, login, checkout, or any form POST. The client snippet rides along in your page and collects device evidence; your server asks Maskbreak for a verdict before the protected action runs, and routes on the reasons array. The example starts in watch mode: it logs each verdict, lets every request through and fails open if Maskbreak is unreachable. After a few days, compare the log with the Events in your dashboard, then uncomment the enforce line; the integration guide has the full enforce checks.

// Score the request before the protected action runs
// Watch mode first: log the verdict, always continue, fail open
const body = req.body || {};  // sentinel.js adds monocle + sentinel_fp to your form
let risk = null;
try {
  const verdictRes = await fetch('https://maskbreak.com/v1/evaluate', {
    method: 'POST',
    signal: AbortSignal.timeout(5000),
    headers: {
      'Authorization': 'Bearer ' + process.env.MASKBREAK_API_KEY,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      token: body.token || body.monocle,  // network evidence
      fingerprintEventId: body.fingerprintEventId || body.sentinel_fp,  // device evidence
      tz: body.tz || body.sentinel_tz
    })
  });
  if (verdictRes.ok) risk = await verdictRes.json();
} catch {}  // unreachable or timed out: your handler still runs
console.log('[maskbreak]', JSON.stringify({
  decision: risk?.decision ?? null, reasons: risk?.reasons ?? null,
  risk_score: risk?.risk_score ?? null, degraded: risk ? !!risk.degraded : null,
  automation: risk?.device?.automation ?? null
}));
// Enforce later: if (risk?.device?.automation) return res.status(403).json({ error: 'Request rejected' });

What an automated session looks like. This is an excerpt of the public sample response, which is built by the same function as a live /v1/evaluate call (the legacy fields are left out):

curl "https://maskbreak.com/v1/evaluate/sample?scenario=bot"

{
  "sample": true,
  "decision": "block",
  "risk_score": 83,
  "network": {
    "vpn": false,
    "proxy": false,
    "datacenter": false,
    "anonymous": false,
    "tor": false,
    "residential": true,
    "service": null
  },
  "device": {
    "antidetect": true,
    "automation": true,
    "emulator": false,
    "virtual_machine": false,
    "incognito": false,
    "privacy_mode": false,
    "ip_blocklisted": false,
    "high_activity": false,
    "visitor_id": "demo_visitor_a8c91b",
    "tampering_score": 0.78
  },
  "reasons": ["antidetect_browser", "automation_detected"],
  "evaluated_in_ms": 28
}

The network is clean here: a residential address, no proxy. The device layer is what blocks it: device.automation is true (reason automation_detected), and the same session also tripped the fake-browser check (antidetect_browser). Either one blocks by default; virtual_machine on its own asks for review, never a block. When the device check could not run, the device object is missing rather than all false, so check for it before you treat a result as clean.

See a verdict before you integrate

Don't take the docs' word for it — run your own connection through the live scanner on the homepage, or point a headless browser at it and watch the verdict flip. Both are keyless previews with a reduced signal set — the full API adds device intelligence and multi-account linking.

The signals that matter here

Automation frameworks, read below the patches. Stealth plugins rewrite the JavaScript surface that naive checks inspect — but the device layer reads the environment underneath: rendering quirks, timing characteristics, and low-level attributes that patched Puppeteer and Playwright sessions don't always fake consistently. When automation evidence is found, the response carries device.automation: true and the automation_detected reason code — a hard signal that blocks by default. The same layer covers the broader headless-browser landscape, from vanilla headless Chrome to hardened forks.

Emulators and VMs: where bot farms actually live. Scaled operations don't run on someone's laptop — they run on Android emulator grids and cloud-provisioned virtual machines. Maskbreak returns emulator_detected and virtual_machine as separate reason codes with separate weights: an emulator is a strong fraud tell, while a VM alone is soft evidence (developers and corporate VDI users live in VMs too), so the score reflects the difference instead of flattening both into "bot".

Datacenter-origin correlation. A lot of automation runs on cloud servers, so every verdict pairs the device evidence with network origin: network.datacenter, the hosting provider when known, and proxy/VPN/Tor flags — built on provider-published IP ranges refreshed daily, not a stale ASN dump. The correlation matters in both directions: a clean-looking browser POSTing from an AWS range is worth a second look, and an automation-flagged device on a residential proxy is still flagged — the device evidence doesn't wash off with a better IP.

Reason codes, not a black box. Every verdict ships the individual signals and a reasons array — automation_detected, emulator_detected, virtual_machine, datacenter_asn, proxy_detected — so your policy lives in your code, not ours. Block hard automation, send VM-only traffic to review, exempt your own monitoring: no CAPTCHA required at any point, which also means no conversion tax on the humans. That routing flexibility is what separates a usable bot signal from a score you have to trust blindly — especially against AI agents whose behavior looks human even when their environment isn't.

What this won't catch — honestly. No bot detection API stops everything, and vendors who claim otherwise are selling you a fairy tale. A human at a real browser doing the abusive work manually — a paid click farm, a CAPTCHA-farm worker walking through your flow — presents genuine human signals, because they are one; you catch those operations on volume patterns and multi-account linking, not automation flags. A brand-new framework can have a window before its artifacts are profiled. And the device layer needs the client snippet to run — a bot that only hits your raw API endpoints and never loads your page yields network signals (datacenter, proxy, blocklist) but no device verdict. Treat Maskbreak as one layer in a stack that still includes rate limits and business-logic checks, not a replacement for all of them.

Common questions

Which API returns an allow, review or block decision for each visitor?
Maskbreak does. One server call, POST /v1/evaluate, checks the visitor's network and browser and answers allow, review or block, with a risk_score from 0 to 100 and the reasons behind it, for example vpn_detected (review), proxy_detected or automation_detected (block). Your app acts on the decision: let the visitor in, ask for a second step, or stop them. Setup starts in watch mode, which only logs the decision, so nobody is blocked while you check the first answers. The Free plan includes 10,000 visitor checks a month with no card; paid plans start at €29 a month.
Which real-time fraud detection API checks web visits before signup, login or checkout?
Maskbreak is built for that. A script on your page collects a network token and a browser check, and your server sends both to POST /v1/evaluate while the visitor waits, before the signup, login or payment goes through. It flags bots and automation, fake (antidetect) browsers, emulators, VPNs, proxies including residential ones, and Tor, names the VPN or proxy service when it is known, and answers allow, review or block. The Free plan includes 10,000 visitor checks a month with no card; paid plans start at €29 a month.
Does Maskbreak detect Puppeteer and Playwright with stealth plugins?
Maskbreak can return device.automation and automation_detected when automation evidence is available. Stealth tools change over time, so no detection of every patched browser is guaranteed. Test representative versions and configurations, and check for missing device evidence before trusting a negative result.
Do I still need a CAPTCHA in front of this?
Maskbreak does not display a CAPTCHA. It returns signals and a decision within your application flow. You choose whether review results need additional verification. Measure collection and response time in your own environment; no fixed global latency is guaranteed.
Will good bots like Googlebot get blocked?
Only if you point the check at them. Maskbreak scores the flows you choose — signups, logins, checkouts, form posts — not your public pages, and search crawlers don't submit your signup form. The decision also stays in your code: the API returns signals and reason codes, and you decide which paths enforce them.
Will real users on VMs or remote desktops be rejected?
virtual_machine is a soft signal, weighted well below automation_detected in the risk score, precisely because developers, corporate VDI users, and privacy-conscious people legitimately browse from VMs. A VM alone won't push a clean session into 'block' — and since every signal is returned individually, you can down-weight it further for your audience.
How much does it cost to try?
Free plan: 10,000 visitor checks a month, no card. Paid plans raise the allowance, from €29 a month for 50,000 checks; larger volumes are on Enterprise. If you want help tuning thresholds for a bot problem, email support@maskbreak.com and a human will answer.

Put a real bot signal in front of your forms

Free plan: 10,000 visitor checks a month, no card. Paid plans from €29 a month. Flags automation, emulators, virtual machines and cloud-server origin on live visits.

Fraud BriefOnce a month · no spam · unsubscribe anytime
Get the new VPN, proxy & bot patterns we see each month
Short, technical breakdowns of what fraudsters changed last month — written for engineers, not marketers.
Put a bot check in front of your forms — try Maskbreak free. Free plan: 10,000 checks a month, no card.