What is traffic quality?
Traffic quality is how much of an acquisition source’s traffic comes from real, unmasked visitors versus sessions that are anonymized, spoofed, or coordinated. A source can look healthy on volume alone while most of its clicks arrive over VPNs, proxies, datacenter IPs, or anti-detect browsers. ShieldLabs grades it by attaching a Risk Score and named anonymity signals to every visit, then rolling those up per channel, referrer, and UTM. The count stays honest because every visit resolves to a durable, server-derived DeviceID. It is computed from the browser environment rather than stored in a cookie, so it survives a cookie clear, an incognito window, and an IP rotation — one machine cannot churn cookies to pose as many “visitors” and inflate a source’s volume.The Risk Score is 0-100, hard-capped, in four bands: Clean (0-9), Low (10-29), Medium (30-59), High (60-100). A higher score means more anonymous or masked traffic, not a confirmed verdict — a legitimate visitor can score high behind a corporate proxy, VPN, or privacy browser. For traffic-quality reporting you read the shape of the distribution across many requests, where individual false positives wash out.
Volume vs quality, in one number
A dashboard that only reports volume treats every session as equal. ShieldLabs adds a per-request risk dimension, so the same 10,000 visits become a quality breakdown you can act on.| Standard analytics | ShieldLabs | |
|---|---|---|
| Unit counted | Sessions, pageviews | Identified requests + Risk Score |
| ”10,000 visits” means | 10,000 equal sessions | A distribution across Clean / Low / Medium / High |
| Sees VPN, proxy, Tor, anti-detect routing | No | Yes, as named signals in signals |
| Returning visitor after cleared cookies | Counted as new | Recognized by DeviceID (same browser) |
| Per-source verdict | Volume and conversions | Volume, conversions, and risk share |
| Bucket | Bands | What is usually in it |
|---|---|---|
| Clean | Clean (0-9), Low (10-29) | Direct connections, ordinary browsers, the bulk of healthy traffic |
| Suspicious | Medium (30-59) | VPN, proxy, privacy relay, datacenter IP, timezone mismatch |
| Dangerous | High (60-100) | Tor, anti-detect browsers, OS mismatch |
signals array with the points it added, and as a boolean in detection_flags.
One comparison earns special attention for reporting. Each scored visit carries two IP objects: public_ip is the public IP and country on the HTTP request, which a VPN or proxy lets a visitor fake; local_ip is the real network IP recovered from an optional follow-up check, which can reveal the network behind the mask. When the two disagree, detection_flags.ip_mismatch is set to true. A source whose visits routinely show public_ip.country differing from local_ip.country is sending masked traffic, no matter how clean the public IP looks.
Grade and act on each source
The whole workflow is three plain steps. ShieldLabs gives you the inputs; the grading rule and the budget call are yours.- Read the anonymous-traffic share per source. For each channel, referrer, and UTM source, read the percentage of its requests in the Medium and High bands. That share is the source’s anonymity grade.
- Rank and flag sources by that share. Sort worst-first. Flag any source whose share crosses a line you set; a low share marks a source you trust as-is.
- Turn the grade into a budget decision. Divide each source’s spend by its real-visitor count, not its raw click count, to get cost per real visitor. Cut or renegotiate the sources paying click prices for masked traffic, keep the ones that look pricey per click but are mostly Clean, and report real-visitor numbers instead of raw volume.
- A channel or campaign with a high Dangerous share is the first place to cut or renegotiate, especially affiliate and referral sources.
- A source that looks expensive per click but is mostly Clean may be your best traffic once reweighted to cost per real visitor.
- Rising Medium and High share over time on Direct or Organic Search is a cue to check the Patterns tab for coordinated activity.
Build it
Reading traffic quality is part dashboard, part export. The snippet feeds both; the first step is the only code on the page.Capture the source on every visit
Add the snippet to the page that receives the traffic. It already collects channel, referrer, and UTM attribution for every request, so the Traffic Sources tables populate without extra work. Make sure your UTM parameters are on the inbound links — ShieldLabs records
utm_source, utm_medium, utm_campaign, utm_content, utm_term, referrer_domain, and the resolved channel per request. The CSP page lists the header requirements.Landing page that paid and organic traffic arrives on
Read the Traffic Score card
On the Overview tab, the Traffic Score card shows a gauge with the band label, a Traffic Risk metric (a 0-100 indicator weighting the concentration of Medium and High requests by signal severity, where lower is better), and Requests Checked. Below the gauge, a stacked bar shows the count and percent of requests in each band: Clean, Low, Medium, High. This is your quality split for all traffic at a glance. Filter by project and date range with the controls at the top.
Rank sources by risk
Open Traffic Sources. The Channels table lists Google Ads, Meta, TikTok, LinkedIn, X, Organic Search, Referral, Direct, and Other. Each row shows requests, traffic share, and a Risk Badge rendered as
<score> <level> (for example 71 High or 8 Clean). Sort by Traffic Risk to find the channel sending the most masked traffic. The Source details table below toggles between Referrers and UTM Parameters, so you can isolate the single affiliate, creative, or campaign delivering anonymous traffic inside an otherwise healthy channel.Export the raw records for BI
Go to the Data tab and use Export to pull the per-request records as CSV. Exports are free (they do not bill requests). The export is the one path that carries per-request source attribution —
channel, referrer_domain, and the utm_* fields — alongside the Score and signal columns, so it is what you join against ad spend.For per-source roll-ups, the boolean detection_flags (vpn, proxy, tor, datacenter_ip, anti_detect_browser, ip_mismatch, suspicious_paid_click, and the rest) aggregate more cleanly than the variable-length signals array. SUM each flag grouped by channel or utm_* to get a masking-share breakdown per source.Compute cost per real visitor
Group the exported rows by source and divide spend by the Clean-bucket count instead of the raw count. That stops you from paying click prices for masked traffic.On a cost-per-click basis
affiliate_x looks cheaper. On a cost-per-real-visitor basis it is more than twice as expensive, because most of its traffic is masked. That is the reallocation decision standard analytics cannot surface. For paid sources specifically, the webhook exposes a ready-made suspicious_paid_click flag in detection_flags, true when a request arrived on a paid channel and scored High (60+), so you can sum it per utm_campaign or channel without re-deriving the channel-plus-score logic. Paying out conversions on top of this is covered in Affiliate Fraud.Read records by identifier
The dashboard and export cover reporting. To read scored records by identifier in real time — to reconcile or enrich a row — use the History API. It returns newest-first snapshots withscore, score_details, and network fields, but not the channel/UTM attribution, so join back to the export on request_id when you need source attribution. History reads through account.shieldlabs.ai are free.
Parse
score_details as JSON. Branch on score and each entry’s Value, not on the human-readable Description label, which can change.request_id and reconcile against the History API for guaranteed completeness.
Test it
Confirm the DeviceID holds before you trust the quality split:Load a page in a normal window
Visit a page with the snippet installed and read the webhook (or the History API). Note the
device_id.Repeat in incognito and after clearing cookies
Open the same page in a private window, then again after clearing cookies and storage. The
cookie_id and visitor_id change, but the device_id stays the same — that is what keeps a returning visitor from counting as new.The dashboard tooltip calls these estimated unique visitors, so do not promise exact counts. The identifiers reference has the full mechanics, and the Visitors view shows how “new” is determined.