How can I identify bot user agents in my email click data?
Published 22 Apr 2025
Updated 8 Aug 2026
11 min read
Summarize with

Updated on 8 Aug 2026: We sharpened the bot-classification rules and added safeguards for automations triggered by nonhuman clicks.
Identify bot user agents in email click data by treating the user agent as the first clue, then confirming it with timing, IP, recipient domain, link pattern, and repeat behavior. A user agent that does not start with Mozilla is often automation, but that rule alone creates false positives.
The direct answer is this: flag obvious automation libraries first, score security scanners and preview services next, then keep human-like browser strings unless the surrounding behavior proves otherwise. The user agent tells you what fetched the link. It does not prove who intended the click, and a browser-like string can be copied or supplied by an intermediary.
- Strong bot: strings such as python-requests, aiohttp, Wget, curl, Java HTTP clients, Jetty, Apache-HttpClient, and lua-resty-http usually mean scripted fetching.
- Likely automated: strings such as Slackbot-LinkExpanding, facebookexternalua, facebookexternalhit, Snap URL Preview Service, and RSS scrapers usually mean link preview or syndication activity.
- Needs context: strings such as Microsoft Office, Microsoft Exchange, dataaccessd, Dalvik, CFNetwork, and okhttp need timing, network, and session checks before exclusion.
The short answer
Start with a simple classification pass. Use four buckets: explicit automation, known preview services, security scanning, and normal mail client or browser activity. Exclude the first bucket from click-rate reporting. Mark the second and third buckets as nonhuman interaction (NHI) unless later activity supplies strong evidence of human intent. Keep the fourth bucket in the report until behavior says otherwise.
Do not use one rule alone
The rule "does not start with Mozilla" is useful, but it is too blunt. Some real mobile and app clients use non-browser user agents, while some security systems use browser-like strings. Treat the prefix as a score input.
- Prefix check: non-Mozilla strings get a higher bot score, not an automatic verdict.
- Fast click: clicks within seconds of delivery often come from scanners or prefetch systems, but timing alone is not proof.
- Link sweep: one visitor hitting every link in a message is rarely a human reading session.
This matters because bot clicks change business decisions. They inflate click-through rate and click-to-open rate, trigger false lead scoring, distort A/B tests, and make unsubscribe or preference-center data harder to interpret. A clean filter has to protect reporting without deleting real buyer intent.

Flowchart for scoring email click user agents with timing and IP context.
Signals that identify bot user agents
The highest-confidence signal is a user agent that names an automation library. A real person does not normally click a newsletter link with Wget or python-requests. Those strings usually mean a script, a scanner, an integration worker, or an internal system fetched the link.
High-confidence bot user-agent patternstext
python-requests Python/3.9 aiohttp Wget/1.9.1 curl/8.7.1 Java/17.0.2 Apache-HttpClient Jetty/9.4 lua-resty-http AHC/2.1 yarn npm node cortex/1.0
Preview services are different. They often fetch a link because a message, feed, or social app wants to show a preview card. These clicks are still not human engagement with the email, but the separate label explains why a contact appears to have clicked before reading.
|
|
|
|---|---|---|
python | Script | Exclude |
Wget or curl | Fetcher | Exclude |
Slackbot | Preview | Suppress |
Office | Client or protection | Score |
Mozilla | Browser-like | Verify |
Compact user-agent triage table.
Keep the table compact because user-agent strings get long quickly and the useful part is the pattern, not the entire string. Store the full raw value in the event table, then classify it into a short normalized label for reporting.
Build a scoring model
A deterministic pattern list is the right start, but a scoring model works better over time. The model does not need machine learning. A few weighted rules are easier to audit and explain to sales and analytics teams.
Example click scoring logicsql
case when ua like '%python-requests%' then 100 when ua like '%aiohttp%' then 100 when ua like '%Wget%' then 100 when ua like '%curl/%' then 100 when ua like '%Slackbot-LinkExpanding%' then 90 when ua like '%facebookexternalua%' then 90 when seconds_after_delivery < 10 then 40 when links_clicked_in_message >= 5 then 30 when same_ip_clicks_many_recipients = true then 30 else 0 end as bot_score
Treat scores of 90 and above as nonhuman. Send scores between 50 and 89 to a review bucket. Keep scores below 50 as human unless another signal appears. This approach stays strict with clear scripts and careful with mail clients that behave strangely.
Bot score bands
A practical threshold model for filtering email click events.
Human
0-49
Keep in reports unless another signal appears.
Review
50-89
Inspect timing, IP, domain, and link pattern.
Bot
90-100
Suppress from engagement and lead scoring.
The exact weights depend on the traffic. B2B lists with enterprise recipients see more security checks. Consumer lists see more app previews and mobile proxy behavior. Keep the scoring rules visible, versioned, and calibrated against confirmed conversions.
Use click context before filtering
The context around the user agent usually confirms the answer. Check the delivery timestamp, recipient domain, source IP, ASN, reverse DNS, geographic location, referrer, clicked URL, and whether the same visitor touched several recipients. A security scanner often clicks immediately, touches several links, and repeats similar behavior across a company domain. Shared corporate egress means the same IP can also carry later human traffic, so IP alone is not a verdict.
Human click pattern
- Timing: the click usually happens after a plausible reading delay.
- Depth: the visitor clicks one or two relevant links, not every link.
- Session: a landing-page visit, scroll, form start, authenticated session, or second page supports intent.
Bot click pattern
- Timing: the click lands seconds after delivery or before a recorded open.
- Depth: the visitor touches every link, including hidden or low-value links.
- Session: there is no normal browser path after the tracked redirect.
Do not require a recorded open before accepting a click as human. Image proxying, blocked tracking pixels, and privacy controls make open data incomplete. Treat click-before-open as one score input and look for later page or conversion activity.
Compare request and network clusters by recipient domain. If one corporate domain has a sudden burst from cloud-hosted IP space, a shared ASN, or Microsoft Office-related strings, that often points to recipient-side protection rather than campaign quality. Some protection systems also rewrite links and verify destinations at the time of a real user's click, so a protection-related request can coexist with human intent. For deeper background on domain authentication, Suped's DMARC monitoring helps separate identity and authentication problems from engagement measurement problems.
To inspect a real message, send it through an email tester before launch. That provides a controlled baseline for headers and authentication issues before campaign traffic adds scanner noise.
Email tester
Send a real email to this address. Suped shows a results button when the test is ready.
?/43tests passed
After that baseline, compare production click events against the controlled test. If the test passes cleanly but one recipient domain still produces immediate multi-link clicks, the likely cause is recipient-side inspection rather than the message setup.
What common user agents usually mean
Some strings deserve special handling because they are common in email click logs. Document them in plain English so analysts know why a click was excluded or kept.
- python-requests: a Python script fetched the URL. Treat it as automation unless there is a known internal integration.
- aiohttp: another Python HTTP client. It is normally scripted and safe to exclude from engagement.
- Cloud-hosted IP or reverse DNS: this is network context, not a user-agent family. Verify the ASN, recipient domain, and request pattern before classifying it.
- Microsoft Office: an Office or Outlook-related fetch. Score it with timing, link sweep behavior, and later session activity.
- dataaccessd: an Apple system process. Do not classify it as human or automated without timing and downstream behavior.
- Dalvik: an Android runtime string. It can be app activity, so use timing and session evidence.
- Slackbot: a link preview fetch. Suppress it from email engagement and keep it in audit logs.
- facebookexternalua or facebookexternalhit: a social preview or app fetch. It is not a newsletter reader click.
Keep raw and normalized values
Store the original user agent, normalized family, bot score, rule version, final decision, and suppression reason. This creates an audit trail when a revenue team asks why a click disappeared from a dashboard.
Keep separate suppression reasons. "Scripted client" and "security scanner" both get removed from click-rate reporting, but they mean different things operationally. The first can indicate scraping or a custom integration. The second can indicate normal recipient protection.
Example click classification mix
Illustrative split after user-agent and behavior scoring.
Human
68%Security
17%Preview
9%Script
6%Protect automations and state-changing links
Nonhuman interaction can do more than inflate a dashboard. A scanner click can enter a contact into an automated journey, change a lead score, record a survey response, or activate a preference link. Classify the event before allowing a click alone to cause a high-impact action.
- Quarantine the first click: record it immediately, but wait for a later human signal such as a form submission, purchase, reply, or authenticated session before sales handoff or a high-value journey.
- Make ordinary GET requests safe: a fetched message link should not confirm consent, cast a vote, change a preference, or submit a form without an intentional next step.
- Handle one-click unsubscribe correctly: keep the RFC 8058 List-Unsubscribe POST flow operational, and do not treat an automated GET fetch as that one-click request.
- Measure downstream intent: compare filtered click-through rate and click-to-open rate with conversion rate, authenticated sessions, and replies.
Use hidden marker links carefully
A hidden honeypot-style link can support a bot score during a controlled test, but the marker must perform no action and must stay out of engagement reports. Some scanners click selected links, wait, or use browser-like behavior, so a marker click is supporting evidence and no marker click is not proof of a human. Review accessibility and message content before production use.
Where Suped fits
Bot user-agent filtering lives inside analytics or ESP data, but it should not be isolated from domain health. Scanner behavior often changes by recipient domain, authentication state, sender reputation, and whether a security gateway trusts the mail. Suped's product connects those signals to the investigation.

Email tester sample report showing total score, email preview, issue summary, and per-section results
Suped's DMARC platform puts DMARC, SPF, DKIM, MTA-STS, authentication alerts, and blocklist (blacklist) monitoring in one domain view. That does not replace click-log filtering. Use the authentication and reputation evidence to investigate why scanners treat one sender, subdomain, or campaign differently.
- Issue detection: Suped flags authentication issues and provides concrete remediation steps.
- Alerts: teams can react when authentication failures or sender changes appear.
- Domain view: SPF, DKIM, DMARC, reputation, and blocklist (blacklist) data appear together.
- MSP workflow: agencies and managed service providers can investigate many domains in one dashboard.
For a quick domain-level check, run the sender through the domain health checker. If bot clicks spike at the same time as authentication failures or reputation movement, treat the engagement change as a deliverability investigation, not only a reporting cleanup.
Operational rules that hold up
The hard part is not finding obvious bots. The hard part is keeping the rules useful when email clients, security gateways, and app previews change behavior. Use rules that are strict enough to protect reporting and transparent enough to revise.
- Normalize first: map raw user agents into stable families before reporting.
- Score second: add timing, IP, ASN, link sweep, recipient-domain, and session context.
- Suppress carefully: remove high-score bot clicks from engagement, but keep them in audit tables.
- Version rules: record the rule set used for each reporting period.
- Review spikes: inspect sudden changes by campaign, domain, sender, source IP, and normalized user-agent family.
If the same unknown user agent appears across several unrelated domains, investigate shared infrastructure. If it appears only in one account or recipient organization, check whether that company has a new mail security layer. If it appears only after one campaign, inspect the links, redirects, and message content.
For more detail on filtering clicks in reports, the guide on bot click filtering covers reporting rules that sit downstream of user-agent classification.
Views from the trenches
Best practices
Classify raw user agents into stable families before building campaign engagement filters.
Pair user-agent rules with timing plus IP and link sweep checks before suppression.
Keep raw bot events in audit tables so teams can explain changes in reported engagement.
Common pitfalls
Treating every non-Mozilla string as a bot removes some app and mobile client activity.
Deleting bot clicks entirely makes later deliverability and security investigations harder.
Using one global rule set without recipient-domain context causes uneven reporting quality.
Expert tips
Start strict with known libraries, then add review bands for scanners and app previews.
Review sudden user-agent spikes by domain and MX pattern before changing campaign reports.
Separate preview fetches from scripted fetches because they imply different follow-up work.
Marketer from Email Geeks says non-Mozilla user agents are a strong first clue, but one client dataset still needs timing and domain checks before final filtering.
2024-02-12 - Email Geeks
Marketer from Email Geeks says Amazon CloudFront appeared often around domains using Microsoft-hosted protection, so MX context helped explain the clicks.
2024-03-08 - Email Geeks
Practical takeaway
Do not build an email bot-click filter from a user-agent prefix alone. Start there, then add timing, IP, ASN, recipient-domain, link, and session behavior. Obvious automation libraries deserve automatic suppression. Preview services and security scanners need separate labels. Browser-like strings need context before removal.
This produces reporting people can trust because human engagement stays visible and automated fetching stops inflating click rates. Every excluded event retains an audit trail. Suped supplies the surrounding authentication and domain-health evidence, while the click log remains the source of truth for user-agent classification.

