Filter OpenAI bot traffic without losing human clicks

Filter OpenAI bot traffic from human ChatGPT clicks using user agents, published IP ranges, server logs and GA4 checks, without counting fetches as visits.

Share
Watercolor illustration of server logs and crawler tracking

How do you separate OpenAI fetches from human ChatGPT clicks?

Exclude GPTBot, OAI-SearchBot and ChatGPT-User requests from human visit metrics, and verify claimed OpenAI identity against its published IP ranges. Measure observable human ChatGPT clicks separately through browser analytics using chatgpt.com referrers or utm_source=chatgpt.com; non-JavaScript fetches appear in server logs rather than ordinary GA4 page tracking.

How to verify that a GPTBot request is really from OpenAI

OpenAI GPTBot verification means checking the request's trusted source IP against the GPTBot ranges linked in OpenAI's crawler documentation. A user-agent string containing GPTBot can be spoofed and is not enough to verify OpenAI origin.

Per the vendor's documentation, OpenAI publishes separate JSON IP-range lists for its bots. Check that documentation for the current URLs and use the GPTBot list for a GPTBot claim. Compare the full address against the published CIDR ranges, including IPv6 where present; a matching text prefix is not a network-range check. Refresh the list rather than relying indefinitely on a copied set of addresses.

Use the original client IP from a trusted edge or correctly configured reverse proxy. An origin log may show only the CDN address. Do not accept an arbitrary forwarded-IP header from the requester. If the original address is unavailable, record the identity as unverified.

For an Nginx combined-format log, this read-only filter selects the user-agent field and prints candidate requests:

awk -F '"' '$6 ~ /GPTBot/ {print}' /var/log/nginx/access.log

Adapt the field selection for other log formats. This finds claims; it does not perform the IP check. Retain timestamp, path, HTTP status and trusted client IP beside the verification result.

A reverse lookup is optional supporting evidence, not a replacement for the published ranges. A plausible hostname alone is insufficient; if you investigate DNS, resolve it forward and check that it returns the original IP. Do not invent a trusted hostname suffix.

If a request claims GPTBot but falls outside the current ranges, first check proxy configuration and list freshness. If the mismatch remains, classify it as unverified and block the impersonating traffic at the WAF under your access policy. Do not trust it as verified OpenAI activity in analytics or count it as a human visit. SearchSeal saves answer evidence; server or edge logs provide this verification evidence.

Filter OpenAI bot traffic from human ChatGPT clicks by separating GPTBot, OAI-SearchBot and ChatGPT-User user agents in request logs, then checking claimed OpenAI identity against its published IP ranges. Count observable human clicks separately using chatgpt.com referrers or utm_source=chatgpt.com in browser analytics; GA4's JavaScript page tag does not see fetches that never run it, while server logs do.

Updated October 2026.

Which OpenAI requests belong outside human metrics?

GPTBot is a training crawler, OAI-SearchBot supports search, and ChatGPT-User fetches pages for some user actions, per OpenAI's crawler documentation. All three are automated requests rather than browser visits by the person reading an answer.

ChatGPT-User is the easy one to misclassify. A person may have asked ChatGPT to read your page, but the resulting fetch is still made by the assistant. That person may never open your website. Exclude the fetch from human sessions while retaining it in a separate request report.

Do not delete the underlying logs to clean up a dashboard. Keep the original records so you can investigate access errors and classification mistakes. A request report and a session report answer different questions and can legitimately contain different totals.

What does each signal establish?

SignalWhat it tells youWhere you see it
GPTBot, OAI-SearchBot or ChatGPT-User tokenClaimed automated requester identityUser-agent field in access logs
Client IP within the matching published rangeEvidence supporting OpenAI originTrusted edge or server logs
chatgpt.com or chat.openai.com referrerRequest or browser visit reports that referring hostReferrer field; analytics source
utm_source=chatgpt.comURL carries a ChatGPT source labelLanding URL; analytics campaign source
Browser page event and subsequent interactionsEvidence of a measured browser session, still subject to spamGA4 or other browser analytics

No single row proves a sale or a citation. A source parameter can be copied, and a user-agent string can be forged. Use the signals together and label uncertainty.

How do you filter server logs by user agent?

For a local Nginx combined-format access log, the quoted user-agent field is field six when splitting on double quotes. This read-only example selects requests claiming one of the three identities:

awk -F '"' '$6 ~ /(GPTBot|OAI-SearchBot|ChatGPT-User)/ {print}' /var/log/nginx/access.log

To inspect the remaining records, invert that user-agent condition:

awk -F '"' '$6 !~ /(GPTBot|OAI-SearchBot|ChatGPT-User)/ {print}' /var/log/nginx/access.log

These commands print matching records; they do not modify the log or create a human-session count. The second command still includes other crawlers, uptime checks, asset requests and potentially forged traffic. Restrict the date range and inspect page requests before drawing conclusions.

Adapt the field name to your own format. In a structured log viewer, apply a user-agent field filter for those tokens and keep client IP, timestamp, path, status and referrer visible. Searching the entire raw line can accidentally match a token inside a URL instead of the user agent.

How do you verify a claimed OpenAI request?

Use the ranges linked from OpenAI's documentation: GPTBot IP ranges, OAI-SearchBot IP ranges and ChatGPT-User IP ranges. Match the client address against the corresponding CIDR ranges, including IPv6 when present, rather than comparing a text prefix.

Behind a reverse proxy, the origin log may contain the proxy's address. Use the client IP recorded by a trusted edge or correctly configured proxy; do not trust an arbitrary forwarded-IP header supplied by a requester. If the original client address is unavailable, mark identity unverified.

Classify a matching token with no verified address as “claimed OpenAI fetcher,” not “human.” Keep it outside human reporting while reviewing the mismatch. The AI crawler user agent checker can help interpret a token, but a token check alone does not authenticate a request.

How do you review the filter before using its totals?

Inspect a few retained records and a few excluded records from the same interval. Confirm that the user-agent field is populated, timestamps use the expected timezone and the client-IP field represents the original requester. A blank user agent should remain unknown rather than becoming a verified human by default.

Group the claimed fetches by token and HTTP status. A successful response, a denied request and a redirect describe different outcomes; keep those distinctions when investigating access. For the browser cohort, count page sessions in analytics rather than adding document, image and script requests from logs. Preserve the filter definition with the report so a later rule change does not silently alter the comparison.

How do you check human ChatGPT clicks in GA4?

In Reports > Acquisition > Traffic acquisition, select Session source and filter for chatgpt.com. Inspect chat.openai.com separately if it appears. Review landing pages, sessions and key events, then compare Session source / medium where the source label needs context.

Inspect the destination URL from an actual ChatGPT link. Some links include utm_source=chatgpt.com, per the vendor's documentation; others may rely on a browser referrer. Keep existing campaign values through redirects so your analytics has a chance to record them. Do not manually relabel an unknown visit just because it landed on a page cited by ChatGPT.

GA4 automatically excludes known bot traffic, but that is not a promise that all automation is removed. With ordinary browser tagging, a bot that never runs the tag sends no page event. Server-side event collection can behave differently; inspect your own implementation before comparing totals.

Why do log requests and GA4 sessions disagree?

One page visit can request multiple files, and a crawler can fetch pages without creating a browser session. Conversely, analytics can miss a browser visit when consent is declined, JavaScript is blocked or the tag fails. Do not expect one request to equal one session.

AI app clicks can also arrive without a referrer or surviving campaign value and appear as Direct. That missing source cannot be recovered just by noticing a nearby ChatGPT-User request. The fetch and the later visit may be unrelated.

Use the ChatGPT referral guide for acquisition setup, the OpenAI crawler guide for request roles, and why fetches do not appear in GA4 for the measurement boundary. SearchSeal saves answer evidence; use server logs for crawler requests and analytics for human visits and outcomes.

Frequently asked questions

Is ChatGPT-User traffic a human visit?

No. A person can trigger the fetch, but the HTTP request is made by ChatGPT. Count a later browser click separately if your analytics observes it.

Does GA4 record GPTBot requests?

An ordinary GA4 browser tag does not record requests that never execute it. GA4 also excludes known bots. Server logs are the place to inspect fetches; server-side analytics setups require their own review.

Is an OpenAI user agent enough to verify a bot?

No. User agents can be forged. Compare the trusted client IP against the corresponding ranges published by OpenAI and record whether that verification was possible.

Does utm_source=chatgpt.com prove a human click?

No. It is an attribution label that can survive copying or be supplied by another requester. Review it alongside browser session evidence and bot filtering.

How do I verify GPTBot traffic?

Compare the trusted source IP with the current GPTBot CIDR ranges linked from OpenAI's crawler documentation. User-agent strings can be spoofed, and reverse DNS alone is insufficient. Check proxy configuration and list freshness before rejecting a mismatch. Keep unresolved requests unverified, block impersonating traffic at the WAF under your policy and exclude it from verified OpenAI and human-visit metrics.

Verified sources

Find your next AI search win

Check your site