Browser protection
Bring the browser behind each claim into the evaluation, with device and automation evidence your server can't see on its own.
Browser protection brings the browser behind each claim into the evaluation. The AbuseZero browser SDK, or the standalone browser script, collects device and automation evidence for the claim and hands your page a device token. Your server sends that token with the evaluation, and AbuseZero assesses the evidence there.
Why it matters
Your server sees an email address and an IP address. It can't see the device or tell whether a real person is at the keyboard. Browser protection gives every evaluation that view, so a second account created on the same device connects to the first, and scripted sign-ups are recognized as scripted.
Key capabilities
- Always on. Browser protection runs on every page that loads the SDK or script. There is nothing to switch on.
- One device token per claim. Evidence is collected for a specific
claimId, travels as one token and is used by that claim's evaluation. - Browser data status. The device token carries the browser data, or the reason there is none, such as declined consent. Every evaluation records exactly what happened in the browser.
- Your sites. AbuseZero accepts browser data only from the HTTPS sites in your site list. Data from anywhere else is refused.
- Script version checks. Script versions that AbuseZero no longer accepts are refused and reported, so outdated pages never feed stale evidence into your evaluations.
- Continuous monitoring. Browser setup shows where the script runs, which version each site uses, and what your last 7 days of evaluations received. When a problem you can fix persists, AbuseZero emails your workspace's owners and admins.
- A consent option. When your
consentcallback resolves tofalse, nothing is collected, and the device token carries the reason instead. The evaluation still runs.
Integration flow
import { init, observe } from "abusezero/browser";
init({ key: "pk_…" }); // once, when your app starts
const { deviceToken } = await observe({ key: "pk_…", claimId });
// Send deviceToken to your server with the sign-up request.const evaluation = await abusezero.evaluate(
{
benefit: "pro_trial",
claim_id: claimId,
subject: { email },
identifiers: { device_token: deviceToken },
},
`claim:${claimId}`,
);- Always send
deviceToken, whatever its status. It carries the browser data, or the reason there is none. - Use the same claim ID in the browser and in the evaluation.
- Consent tools that block the script: if your consent tool keeps the script from loading at all, send
unavailable:not_loadedas the device token.
Evaluations run without browser data too, with less evidence to work with.
Set up browser protection walks through the integration, including the standalone script for sites without a bundler.
Browser data statuses
Each evaluation records what it received from the browser as browser_data:
| Status | Meaning | You can fix it |
|---|---|---|
collected | Browser data arrived and was used. | |
consent_declined | The visitor declined consent, so nothing was collected. | |
not_loaded | Your consent tool kept the script from loading. | |
blocked | A blocker in the visitor's browser stopped collection. | |
timed_out | Collection didn't finish in time. | |
failed | Collection failed in the browser. | |
site_not_listed | The page's site isn't in your site list. | Yes: add the site in Developers → Browser setup. |
sdk_outdated | The page uses a script version AbuseZero no longer accepts. | Yes: update the SDK or script. |
expired | The token arrived after it expired. | Send the evaluation sooner after collection. |
not_passed_on | The browser collected data, but your server sent the evaluation without the token. | Yes: pass deviceToken through as identifiers.device_token. |
not_sent | The evaluation carried no browser data, and none was collected for the claim. | Add the SDK to the page where the claim starts. |
Declined consent, blockers and similar losses are expected on any site. They never count as a broken setup.
Configuration
- Your site list. Up to 20 HTTPS origins, in Developers → Browser setup or with
PATCH /v1/browser-collection. - Consent. Pass a
consentcallback toobserve. When it resolves tofalse, nothing is collected. CallforgetBrowser()when a visitor withdraws consent. - A bot check at submit time. Call
prepareBotObservationinstead ofobservewhen the person submits. See Bots and AI agents. - Content Security Policy. If your site sets one, copy the sources shown in Developers → Browser setup into it.
Programmatic access
| Interface | Use |
|---|---|
| AbuseZero REST API | GET /v1/browser-collection, PATCH /v1/browser-collection |
| AbuseZero browser SDK | init(), observe(), prepareBotObservation(), forgetBrowser(), and the standalone browser script |
| AbuseZero Node.js SDK | browserCollection(), updateBrowserCollection() |
| AbuseZero CLI | abusezero browser-collection get, update |
| AbuseZero MCP server | abusezero_get_browser_collection, abusezero_update_browser_collection |
| Dashboard | Developers → Browser setup |
Response data
- On each evaluation:
browser_data, plus thedeviceandbrowserinputs. - For your whole workspace:
GET /v1/browser-collectionreturns your site list, every site where the script has been seen with its version, the current problem if there is one, and a 7-day breakdown of the statuses above.
{
"object": "browser_collection",
"origins": ["https://app.example.com"],
"revision": 2,
"sites": [
{ "origin": "https://app.example.com", "listed": true, "first_seen_at": "2026-10-02T10:14:00.000Z", "last_seen_at": "2026-10-29T08:51:00.000Z", "sdk_version": "0.11.0" }
],
"issue": null,
"issue_since": null,
"coverage": { "days": 7, "total": 1840, "collected": 1712, "consent_declined": 96, "not_loaded": 0, "blocked": 21, "timed_out": 6, "failed": 2, "site_not_listed": 0, "sdk_outdated": 0, "expired": 3, "not_passed_on": 0, "not_sent": 0 },
"notices": []
}Next steps
How is this guide?
Last updated on