[{"data":1,"prerenderedAt":1673},["ShallowReactive",2],{"navigation_docs":3,"-connectors-cloudflare-ai-crawlers":164,"-connectors-cloudflare-ai-crawlers-surround":1668},[4,23,45,90,108,126,144],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":22},"Getting started","i-lucide-rocket","/getting-started","1.getting-started",[10,14,18],{"title":11,"path":12,"stem":13},"Introduction","/getting-started/introduction","1.getting-started/1.introduction",{"title":15,"path":16,"stem":17},"Quickstart","/getting-started/quickstart","1.getting-started/2.quickstart",{"title":19,"path":20,"stem":21},"Core concepts","/getting-started/concepts","1.getting-started/3.concepts",false,{"title":24,"icon":25,"path":26,"stem":27,"children":28,"page":22},"Tracking SDK","i-lucide-chart-line","/tracking-sdk","2.tracking-sdk",[29,33,37,41],{"title":30,"path":31,"stem":32},"Overview","/tracking-sdk/overview","2.tracking-sdk/1.overview",{"title":34,"path":35,"stem":36},"JavaScript SDK","/tracking-sdk/javascript","2.tracking-sdk/2.javascript",{"title":38,"path":39,"stem":40},"Events reference","/tracking-sdk/events","2.tracking-sdk/3.events",{"title":42,"path":43,"stem":44},"Event schema","/tracking-sdk/event-schema","2.tracking-sdk/4.event-schema",{"title":46,"icon":47,"path":48,"stem":49,"children":50,"page":22},"Connectors","i-lucide-plug","/connectors","3.connectors",[51,54,58,62,66,70,74,78,82,86],{"title":30,"path":52,"stem":53},"/connectors/overview","3.connectors/1.overview",{"title":55,"path":56,"stem":57},"Cloudflare AI crawlers","/connectors/cloudflare-ai-crawlers","3.connectors/10.cloudflare-ai-crawlers",{"title":59,"path":60,"stem":61},"Google Ads","/connectors/google-ads","3.connectors/2.google-ads",{"title":63,"path":64,"stem":65},"Meta Ads","/connectors/meta-ads","3.connectors/3.meta-ads",{"title":67,"path":68,"stem":69},"TikTok Ads","/connectors/tiktok-ads","3.connectors/4.tiktok-ads",{"title":71,"path":72,"stem":73},"LinkedIn Ads","/connectors/linkedin-ads","3.connectors/5.linkedin-ads",{"title":75,"path":76,"stem":77},"Pinterest Ads","/connectors/pinterest-ads","3.connectors/6.pinterest-ads",{"title":79,"path":80,"stem":81},"Custom webhooks","/connectors/webhooks","3.connectors/7.webhooks",{"title":83,"path":84,"stem":85},"PrestaShop","/connectors/prestashop","3.connectors/8.prestashop",{"title":87,"path":88,"stem":89},"WooCommerce","/connectors/woocommerce","3.connectors/9.woocommerce",{"title":91,"icon":92,"path":93,"stem":94,"children":95,"page":22},"Attribution","i-lucide-git-fork","/attribution","4.attribution",[96,100,104],{"title":97,"path":98,"stem":99},"How attribution works","/attribution/overview","4.attribution/1.overview",{"title":101,"path":102,"stem":103},"Data-driven model","/attribution/data-driven","4.attribution/2.data-driven",{"title":105,"path":106,"stem":107},"Attribution windows","/attribution/windows","4.attribution/3.windows",{"title":109,"icon":110,"path":111,"stem":112,"children":113,"page":22},"Dashboard","i-lucide-layout-dashboard","/dashboard","5.dashboard",[114,118,122],{"title":115,"path":116,"stem":117},"Dashboard overview","/dashboard/overview","5.dashboard/1.overview",{"title":119,"path":120,"stem":121},"Metrics reference","/dashboard/metrics","5.dashboard/2.metrics",{"title":123,"path":124,"stem":125},"Alerts","/dashboard/alerts","5.dashboard/3.alerts",{"title":127,"icon":128,"path":129,"stem":130,"children":131,"page":22},"Lumen","i-lucide-shield-check","/lumen","6.lumen",[132,136,140],{"title":133,"path":134,"stem":135},"Lumen overview","/lumen/overview","6.lumen/1.overview",{"title":137,"path":138,"stem":139},"Setup","/lumen/setup","6.lumen/2.setup",{"title":141,"path":142,"stem":143},"Investigations","/lumen/investigations","6.lumen/3.investigations",{"title":145,"icon":146,"path":147,"stem":148,"children":149,"page":22},"MCP agent","i-lucide-bot","/mcp-agent","7.mcp-agent",[150,153,156,160],{"title":30,"path":151,"stem":152},"/mcp-agent/overview","7.mcp-agent/1.overview",{"title":15,"path":154,"stem":155},"/mcp-agent/quickstart","7.mcp-agent/2.quickstart",{"title":157,"path":158,"stem":159},"Tools reference","/mcp-agent/tools-reference","7.mcp-agent/3.tools-reference",{"title":161,"path":162,"stem":163},"SEO × GEO playbook","/mcp-agent/playbook-seo-geo","7.mcp-agent/4.playbook-seo-geo",{"id":165,"title":55,"body":166,"description":1661,"extension":1662,"links":1663,"meta":1664,"navigation":1665,"path":56,"seo":1666,"stem":57,"__hash__":1667},"docs/3.connectors/10.cloudflare-ai-crawlers.md",{"type":167,"value":168,"toc":1639},"minimark",[169,178,201,204,209,268,271,276,313,320,324,331,1117,1121,1124,1165,1190,1193,1197,1290,1293,1295,1299,1305,1325,1328,1330,1333,1339,1365,1369,1403,1407,1410,1414,1428,1430,1434,1447,1450,1454,1488,1492,1498,1539,1551,1555,1569,1596,1603,1607,1620,1622,1635],[170,171,172,173,177],"p",{},"AI crawlers like GPTBot, ClaudeBot and PerplexityBot don't run JavaScript. They hit ",[174,175,176],"code",{},"/robots.txt",", sitemaps and raw HTML endpoints, so the TrustData JS SDK never sees them. A Cloudflare Worker deployed on your zone classifies every request at the edge and forwards a small log line to TrustData. Each forwarded hit is one of:",[179,180,181,189,195],"ul",{},[182,183,184,188],"li",{},[185,186,187],"strong",{},"AI bot visit",": the user agent matches a known AI crawler",[182,190,191,194],{},[185,192,193],{},"AI referral visit",": the referrer is an AI engine (chatgpt.com, perplexity.ai, claude.ai, …) and the visitor is human",[182,196,197,200],{},[185,198,199],{},"Traffic sample",": a small anonymized share (~2% by default) of everything else, used only as the denominator for AI-share metrics",[170,202,203],{},"All other traffic never leaves your zone. The Worker matches against a bot list it syncs from TrustData every few hours, so brand-new crawlers are picked up without a redeploy.",[205,206,208],"h2",{"id":207},"how-it-works","How it works",[210,211,216],"pre",{"className":212,"code":213,"language":214,"meta":215,"style":215},"language-mermaid shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","flowchart TD\n  Z[\"Your Cloudflare zone\u003Cbr/>(100% of traffic)\"]\n  W[\"TrustData Worker\u003Cbr/>(ai-bot-collector)\"]\n  C[\"TrustData classifies\u003Cbr/>AI bot? · AI referral?\u003Cbr/>else → ~2% kept as a sample\"]\n  L[\"Live Events view\u003Cbr/>(AI bot / AI referral badges)\u003Cbr/>+ daily rollups in your dashboard\"]\n  Z -->|every request wrapped by the Worker| W\n  W -->|forwards a small log line| C\n  C --> L\n","mermaid","",[174,217,218,226,232,238,244,250,256,262],{"__ignoreMap":215},[219,220,223],"span",{"class":221,"line":222},"line",1,[219,224,225],{},"flowchart TD\n",[219,227,229],{"class":221,"line":228},2,[219,230,231],{},"  Z[\"Your Cloudflare zone\u003Cbr/>(100% of traffic)\"]\n",[219,233,235],{"class":221,"line":234},3,[219,236,237],{},"  W[\"TrustData Worker\u003Cbr/>(ai-bot-collector)\"]\n",[219,239,241],{"class":221,"line":240},4,[219,242,243],{},"  C[\"TrustData classifies\u003Cbr/>AI bot? · AI referral?\u003Cbr/>else → ~2% kept as a sample\"]\n",[219,245,247],{"class":221,"line":246},5,[219,248,249],{},"  L[\"Live Events view\u003Cbr/>(AI bot / AI referral badges)\u003Cbr/>+ daily rollups in your dashboard\"]\n",[219,251,253],{"class":221,"line":252},6,[219,254,255],{},"  Z -->|every request wrapped by the Worker| W\n",[219,257,259],{"class":221,"line":258},7,[219,260,261],{},"  W -->|forwards a small log line| C\n",[219,263,265],{"class":221,"line":264},8,[219,266,267],{},"  C --> L\n",[205,269,137],{"id":270},"setup",[272,273,275],"h3",{"id":274},"_1-issue-an-api-key","1. Issue an API key",[277,278,279,289,303,310],"ol",{},[182,280,281,282,285,286],{},"In your organization settings, open the ",[185,283,284],{},"Integrations"," tab → ",[185,287,288],{},"Log ingest keys",[182,290,291,292,295,296,299,300],{},"Pick ",[185,293,294],{},"Cloudflare Worker"," (or ",[185,297,298],{},"Cloudflare Logpush"," for Enterprise) as the provider, name the key, and click ",[185,301,302],{},"Issue ingest key",[182,304,305,306,309],{},"Optionally pin a ",[185,307,308],{},"default attribution ID",". The Worker will tag events with this ID when the payload omits one",[182,311,312],{},"Copy the key immediately, as it is shown only once",[170,314,315,316,319],{},"Keys use the format ",[174,317,318],{},"td_cf_\u003Crandom>",". Only the prefix and a SHA-256 hash are stored in TrustData; the full key cannot be recovered. If lost, revoke it and generate a new one.",[272,321,323],{"id":322},"_2-send-logs-to-trustdata","2. Send logs to TrustData",[170,325,326,327,330],{},"Pick your ingest method. Most zones use the Worker; Cloudflare Enterprise customers can forward the same data over Logpush with no Worker. Both authenticate with the ",[174,328,329],{},"td_cf_..."," key from step 1.",[332,333,334,1014],"tabs",{},[335,336,338,341,344,356,366,390,395,398,472,597,602,610,647,654,982],"tabs-item",{"icon":337,"label":294},"i-lucide-box",[170,339,340],{},"The TrustData AI-bot collector is an open-source Cloudflare Worker you deploy on your own zone. It runs as middleware on every request, clones the response to read size/status, and fires a JSON payload at TrustData. It never alters the response.",[170,342,343],{},"Deploy it straight from the repository, no terminal needed:",[170,345,346],{},[185,347,348,349],{},"→ ",[350,351,355],"a",{"href":352,"rel":353},"https://github.com/trstdata/trustdata-integrations/tree/main/cloudflare/ai-bot-collector",[354],"nofollow","TrustData AI-bot collector on GitHub",[170,357,358,359,362,363,365],{},"Click ",[185,360,361],{},"Deploy to Cloudflare"," in the repo's README. The guided setup runs entirely in your browser: it clones the repo to your account, auto-provisions the KV namespace, prompts for your ",[174,364,329],{}," API key (from step 1) and your attribution ID, then deploys the Worker to your zone.",[367,368,370,373,374,377,378,381,382,385,386,389],"callout",{"icon":369},"i-lucide-triangle-alert",[185,371,372],{},"Required after deploy: add your route, or nothing is captured."," The Deploy button can't set up routing (Cloudflare's deploy flow never asks which zone you own), so a freshly deployed Worker is live but sees ",[185,375,376],{},"no traffic",": it only answers at its ",[174,379,380],{},"*.workers.dev"," URL, which crawlers never hit. In the Cloudflare dashboard, open ",[185,383,384],{},"Workers & Pages → trustdata-ai-bot-collector → Settings → Domains & Routes → Add route",", pick your zone, and set ",[174,387,388],{},"*.yourdomain.com/*"," (adjust to your traffic shape). Only then does the Worker wrap your site's traffic and start picking up AI bots.",[391,392,394],"h4",{"id":393},"no-github-or-gitlab-account","No GitHub or GitLab account?",[170,396,397],{},"The Deploy button forks the repo into a Git account. If you don't have one, build the Worker by hand in the Cloudflare dashboard, with copy-paste only, no terminal, no Git:",[277,399,400,410,428,449,463],{},[182,401,402,405,406,409],{},[185,403,404],{},"Workers & Pages → Create → Start with Hello World → Deploy."," Open the new Worker and click ",[185,407,408],{},"Edit code",".",[182,411,412,413,420,421,424,425,409],{},"Open the collector's bundled code, ",[350,414,417],{"href":415,"rel":416},"https://github.com/trstdata/trustdata-integrations/blob/main/cloudflare/ai-bot-collector/worker.bundle.js",[354],[174,418,419],{},"worker.bundle.js"," on GitHub (viewing needs no account). Click ",[185,422,423],{},"Copy raw file",", paste it over the default code in the editor (replace everything), and click ",[185,426,427],{},"Deploy",[182,429,430,433,434,437,438,441,442,444,445,448],{},[185,431,432],{},"Settings → Variables and Secrets:"," add each row from the table below. Add ",[174,435,436],{},"TRUSTDATA_API_KEY"," as type ",[185,439,440],{},"Secret"," (your ",[174,443,329],{}," key from step 1); add the rest as plaintext ",[185,446,447],{},"Text"," vars.",[182,450,451,454,455,458,459,462],{},[185,452,453],{},"Settings → Bindings → Add → KV namespace:"," create one (any name, e.g. ",[174,456,457],{},"webmcp_cache",") and bind it as ",[174,460,461],{},"WEBMCP_CACHE",". Optional: skip it to disable WebMCP manifest caching.",[182,464,465,468,469,471],{},[185,466,467],{},"Settings → Domains & Routes → Add → Route:"," set ",[174,470,388],{}," so the Worker sees traffic.",[473,474,475,491],"table",{},[476,477,478],"thead",{},[479,480,481,485,488],"tr",{},[482,483,484],"th",{},"Variable",[482,486,487],{},"Type",[482,489,490],{},"Purpose",[492,493,494,511,530,545,565,580],"tbody",{},[479,495,496,502,505],{},[497,498,499],"td",{},[174,500,501],{},"TRUSTDATA_INGEST_URL",[497,503,504],{},"var",[497,506,507,508],{},"Pre-filled to ",[174,509,510],{},"https://t.trustdata.tech/v1/logs/cloudflare_worker",[479,512,513,518,520],{},[497,514,515],{},[174,516,517],{},"TRUSTDATA_ATTRIBUTION_ID",[497,519,504],{},[497,521,522,523],{},"Your attribution ID UUID from ",[185,524,525,526,529],{},"Analytics → Properties → ",[219,527,528],{},"your property"," → Attribution IDs",[479,531,532,537,539],{},[497,533,534],{},[174,535,536],{},"TRUSTDATA_BOTLIST_URL",[497,538,504],{},[497,540,507,541,544],{},[174,542,543],{},"https://t.trustdata.tech/v1/config/ai-bots",". The Worker refreshes its edge bot list from here every ~6 hours, so new crawlers are covered without a redeploy",[479,546,547,552,554],{},[497,548,549],{},[174,550,551],{},"TRUSTDATA_SAMPLE_RATE",[497,553,504],{},[497,555,556,557,560,561,564],{},"Share of non-AI traffic forwarded as an anonymized sample. Default ",[174,558,559],{},"0.02"," (2%). Set to ",[174,562,563],{},"0"," to forward AI traffic only",[479,566,567,572,574],{},[497,568,569],{},[174,570,571],{},"TRUSTDATA_MANIFEST_URL",[497,573,504],{},[497,575,507,576,579],{},[174,577,578],{},"https://app.trustdata.tech/api/v1/webmcp",". Powers WebMCP hosting (see below); leave empty to disable",[479,581,582,586,591],{},[497,583,584],{},[174,585,436],{},[497,587,588],{},[185,589,590],{},"secret",[497,592,593,594,596],{},"The ",[174,595,329],{}," key from step 1",[170,598,599],{},[185,600,601],{},"Endpoint",[210,603,608],{"className":604,"code":606,"language":607},[605],"language-text","POST https://t.trustdata.tech/v1/logs/cloudflare_worker\n","text",[174,609,606],{"__ignoreMap":215},[473,611,612,622],{},[476,613,614],{},[479,615,616,619],{},[482,617,618],{},"Header",[482,620,621],{},"Value",[492,623,624,635],{},[479,625,626,631],{},[497,627,628],{},[174,629,630],{},"X-API-Key",[497,632,633],{},[174,634,329],{},[479,636,637,642],{},[497,638,639],{},[174,640,641],{},"Content-Type",[497,643,644],{},[174,645,646],{},"application/json",[170,648,649,650,653],{},"Body is a JSON ",[185,651,652],{},"array"," of log objects (batched: today one element per request, growing into larger batches without a wire-format change):",[210,655,659],{"className":656,"code":657,"language":658,"meta":215,"style":215},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","[\n  {\n    \"timestamp\": 1740000000000,\n    \"attribution_id\": \"prop-uuid\",\n    \"host\": \"example.com\",\n    \"method\": \"GET\",\n    \"pathname\": \"/blog/post\",\n    \"query_params\": { \"utm_source\": \"chatgpt\" },\n    \"ip\": null,\n    \"user_agent\": \"Mozilla/5.0 (compatible; GPTBot/1.0; …)\",\n    \"referer\": \"\",\n    \"status\": 200,\n    \"bytes\": 4821,\n    \"country\": \"US\",\n    \"asn\": 13335,\n    \"verified\": true,\n    \"verified_by\": \"signature\"\n  }\n]\n","json",[174,660,661,667,672,694,716,736,756,776,810,825,846,863,880,897,918,935,950,970,976],{"__ignoreMap":215},[219,662,663],{"class":221,"line":222},[219,664,666],{"class":665},"sMK4o","[\n",[219,668,669],{"class":221,"line":228},[219,670,671],{"class":665},"  {\n",[219,673,674,677,681,684,687,691],{"class":221,"line":234},[219,675,676],{"class":665},"    \"",[219,678,680],{"class":679},"spNyl","timestamp",[219,682,683],{"class":665},"\"",[219,685,686],{"class":665},":",[219,688,690],{"class":689},"sbssI"," 1740000000000",[219,692,693],{"class":665},",\n",[219,695,696,698,701,703,705,708,712,714],{"class":221,"line":240},[219,697,676],{"class":665},[219,699,700],{"class":679},"attribution_id",[219,702,683],{"class":665},[219,704,686],{"class":665},[219,706,707],{"class":665}," \"",[219,709,711],{"class":710},"sfazB","prop-uuid",[219,713,683],{"class":665},[219,715,693],{"class":665},[219,717,718,720,723,725,727,729,732,734],{"class":221,"line":246},[219,719,676],{"class":665},[219,721,722],{"class":679},"host",[219,724,683],{"class":665},[219,726,686],{"class":665},[219,728,707],{"class":665},[219,730,731],{"class":710},"example.com",[219,733,683],{"class":665},[219,735,693],{"class":665},[219,737,738,740,743,745,747,749,752,754],{"class":221,"line":252},[219,739,676],{"class":665},[219,741,742],{"class":679},"method",[219,744,683],{"class":665},[219,746,686],{"class":665},[219,748,707],{"class":665},[219,750,751],{"class":710},"GET",[219,753,683],{"class":665},[219,755,693],{"class":665},[219,757,758,760,763,765,767,769,772,774],{"class":221,"line":258},[219,759,676],{"class":665},[219,761,762],{"class":679},"pathname",[219,764,683],{"class":665},[219,766,686],{"class":665},[219,768,707],{"class":665},[219,770,771],{"class":710},"/blog/post",[219,773,683],{"class":665},[219,775,693],{"class":665},[219,777,778,780,783,785,787,790,792,796,798,800,802,805,807],{"class":221,"line":264},[219,779,676],{"class":665},[219,781,782],{"class":679},"query_params",[219,784,683],{"class":665},[219,786,686],{"class":665},[219,788,789],{"class":665}," {",[219,791,707],{"class":665},[219,793,795],{"class":794},"sBMFI","utm_source",[219,797,683],{"class":665},[219,799,686],{"class":665},[219,801,707],{"class":665},[219,803,804],{"class":710},"chatgpt",[219,806,683],{"class":665},[219,808,809],{"class":665}," },\n",[219,811,813,815,818,820,822],{"class":221,"line":812},9,[219,814,676],{"class":665},[219,816,817],{"class":679},"ip",[219,819,683],{"class":665},[219,821,686],{"class":665},[219,823,824],{"class":665}," null,\n",[219,826,828,830,833,835,837,839,842,844],{"class":221,"line":827},10,[219,829,676],{"class":665},[219,831,832],{"class":679},"user_agent",[219,834,683],{"class":665},[219,836,686],{"class":665},[219,838,707],{"class":665},[219,840,841],{"class":710},"Mozilla/5.0 (compatible; GPTBot/1.0; …)",[219,843,683],{"class":665},[219,845,693],{"class":665},[219,847,849,851,854,856,858,861],{"class":221,"line":848},11,[219,850,676],{"class":665},[219,852,853],{"class":679},"referer",[219,855,683],{"class":665},[219,857,686],{"class":665},[219,859,860],{"class":665}," \"\"",[219,862,693],{"class":665},[219,864,866,868,871,873,875,878],{"class":221,"line":865},12,[219,867,676],{"class":665},[219,869,870],{"class":679},"status",[219,872,683],{"class":665},[219,874,686],{"class":665},[219,876,877],{"class":689}," 200",[219,879,693],{"class":665},[219,881,883,885,888,890,892,895],{"class":221,"line":882},13,[219,884,676],{"class":665},[219,886,887],{"class":679},"bytes",[219,889,683],{"class":665},[219,891,686],{"class":665},[219,893,894],{"class":689}," 4821",[219,896,693],{"class":665},[219,898,900,902,905,907,909,911,914,916],{"class":221,"line":899},14,[219,901,676],{"class":665},[219,903,904],{"class":679},"country",[219,906,683],{"class":665},[219,908,686],{"class":665},[219,910,707],{"class":665},[219,912,913],{"class":710},"US",[219,915,683],{"class":665},[219,917,693],{"class":665},[219,919,921,923,926,928,930,933],{"class":221,"line":920},15,[219,922,676],{"class":665},[219,924,925],{"class":679},"asn",[219,927,683],{"class":665},[219,929,686],{"class":665},[219,931,932],{"class":689}," 13335",[219,934,693],{"class":665},[219,936,938,940,943,945,947],{"class":221,"line":937},16,[219,939,676],{"class":665},[219,941,942],{"class":679},"verified",[219,944,683],{"class":665},[219,946,686],{"class":665},[219,948,949],{"class":665}," true,\n",[219,951,953,955,958,960,962,964,967],{"class":221,"line":952},17,[219,954,676],{"class":665},[219,956,957],{"class":679},"verified_by",[219,959,683],{"class":665},[219,961,686],{"class":665},[219,963,707],{"class":665},[219,965,966],{"class":710},"signature",[219,968,969],{"class":665},"\"\n",[219,971,973],{"class":221,"line":972},18,[219,974,975],{"class":665},"  }\n",[219,977,979],{"class":221,"line":978},19,[219,980,981],{"class":665},"]\n",[170,983,984,985,987,988,991,992,994,995,997,998,1001,1002,1005,1006,1009,1010,1013],{},"For a matched AI bot the Worker omits the raw ",[174,986,817],{}," (sends ",[174,989,990],{},"null",") and adds the edge anti-spoof verdict in ",[174,993,942],{}," / ",[174,996,957],{},": ",[174,999,1000],{},"\"signature\""," for a Web Bot Auth request signature, or ",[174,1003,1004],{},"\"edge_cidr\""," for a published IP-range match. Anonymized traffic samples instead carry a ",[174,1007,1008],{},"sample_rate"," field and a truncated IP; weight them by ",[174,1011,1012],{},"1 / sample_rate"," to estimate total traffic.",[335,1015,1018,1028,1032,1038,1044,1050,1093,1098,1101,1107],{"icon":1016,"label":1017},"i-lucide-cloud-cog","Logpush (Enterprise)",[170,1019,1020,1021,1024,1025,1027],{},"Cloudflare Enterprise can push edge logs straight to TrustData with no Worker. Create a Logpush job to an ",[185,1022,1023],{},"HTTP destination"," pointing at the endpoint below, using Cloudflare's native field names. Same ",[174,1026,329],{}," key, different payload format.",[170,1029,1030],{},[185,1031,601],{},[210,1033,1036],{"className":1034,"code":1035,"language":607},[605],"POST https://t.trustdata.tech/v1/logs/cloudflare_logpush\n",[174,1037,1035],{"__ignoreMap":215},[170,1039,1040,1041,1043],{},"Authentication accepts either an ",[174,1042,630],{}," header or, for Cloudflare's HTTP destination which cannot set custom headers, the header-injection query parameter:",[210,1045,1048],{"className":1046,"code":1047,"language":607},[605],"?header_X-API-Key=td_cf_...&attribution_id=\u003Cprop-uuid>\n",[174,1049,1047],{"__ignoreMap":215},[170,1051,1052,1053,1056,1057,1056,1060,1056,1063,1056,1066,1056,1069,1056,1072,1056,1075,1056,1078,1056,1081,1084,1085,1088,1089,1092],{},"Body is NDJSON (one log line per newline), using Cloudflare's native field names: ",[174,1054,1055],{},"EdgeStartTimestamp",", ",[174,1058,1059],{},"ClientRequestHost",[174,1061,1062],{},"ClientRequestMethod",[174,1064,1065],{},"ClientRequestURI",[174,1067,1068],{},"ClientRequestUserAgent",[174,1070,1071],{},"ClientRequestReferer",[174,1073,1074],{},"ClientIP",[174,1076,1077],{},"ClientCountry",[174,1079,1080],{},"EdgeResponseStatus",[174,1082,1083],{},"EdgeResponseBytes",". If your zone has Bot Management, also send ",[174,1086,1087],{},"VerifiedBotCategory",": when it carries an ",[174,1090,1091],{},"AI_*"," value Cloudflare has already IP-validated the bot, so TrustData trusts it directly and skips its own check.",[170,1094,1095],{},[185,1096,1097],{},"Optional: filter at the edge to cut volume",[170,1099,1100],{},"A plain \"HTTP requests\" job forwards every line and lets TrustData classify it. To reduce egress, add a Logpush filter so only AI traffic leaves your zone:",[210,1102,1105],{"className":1103,"code":1104,"language":607},[605],"VerifiedBotCategory in [AI_CRAWLER, AI_ASSISTANT, AI_SEARCH]\n  or ClientRequestReferer contains \"chatgpt\"\n  or ClientRequestReferer contains \"perplexity\"\n  or ClientRequestReferer contains \"claude.ai\"\n  or ClientRequestReferer contains \"gemini\"\n  or ClientRequestReferer contains \"copilot\"\n",[174,1106,1104],{"__ignoreMap":215},[367,1108,1109,1110,1113,1114,1116],{"icon":369},"This filter is ",[185,1111,1112],{},"static",". A new AI crawler that isn't already in ",[174,1115,1087],{}," or this referrer list won't be forwarded, so TrustData can't classify it retroactively. The Worker has no such limit, since it refreshes its bot list from TrustData every few hours. Leave the filter off for full retroactive coverage if you don't mind the extra log volume. Logpush also forwards no traffic sample, so AI-share denominators are Worker-only.",[272,1118,1120],{"id":1119},"_3-verify","3. Verify",[170,1122,1123],{},"From any terminal, simulate a GPTBot visit:",[210,1125,1129],{"className":1126,"code":1127,"language":1128,"meta":215,"style":215},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","curl -X POST \\\n  https://your-domain.com/ \\\n  -H \"User-Agent: Mozilla/5.0 (compatible; GPTBot/1.0; +https://openai.com/gptbot)\"\n","bash",[174,1130,1131,1146,1153],{"__ignoreMap":215},[219,1132,1133,1136,1139,1142],{"class":221,"line":222},[219,1134,1135],{"class":794},"curl",[219,1137,1138],{"class":710}," -X",[219,1140,1141],{"class":710}," POST",[219,1143,1145],{"class":1144},"sTEyZ"," \\\n",[219,1147,1148,1151],{"class":221,"line":228},[219,1149,1150],{"class":710},"  https://your-domain.com/",[219,1152,1145],{"class":1144},[219,1154,1155,1158,1160,1163],{"class":221,"line":234},[219,1156,1157],{"class":710},"  -H",[219,1159,707],{"class":665},[219,1161,1162],{"class":710},"User-Agent: Mozilla/5.0 (compatible; GPTBot/1.0; +https://openai.com/gptbot)",[219,1164,969],{"class":665},[170,1166,1167,1168,1171,1172,1175,1176,1185,1186,409],{},"Within ~60 seconds the event should appear in the ",[185,1169,1170],{},"Live Events"," view for your attribution ID, tagged with an ",[174,1173,1174],{},"AI bot"," badge. Navigate via ",[185,1177,525,1178,1180,1181,1184],{},[219,1179,528],{}," → Attribution IDs → ",[219,1182,1183],{},"your attribution ID"," → Live Events",". If not, see ",[350,1187,1189],{"href":1188},"#troubleshooting","Troubleshooting",[1191,1192],"hr",{},[205,1194,1196],{"id":1195},"what-gets-captured","What gets captured",[473,1198,1199,1212],{},[476,1200,1201],{},[479,1202,1203,1206,1209],{},[482,1204,1205],{},"Badge",[482,1207,1208],{},"Trigger",[482,1210,1211],{},"Example",[492,1213,1214,1243,1264,1276],{},[479,1215,1216,1220,1223],{},[497,1217,1218],{},[185,1219,1174],{},[497,1221,1222],{},"User agent matches a known AI crawler",[497,1224,1225,1056,1228,1056,1231,1056,1234,1056,1237,1056,1240],{},[174,1226,1227],{},"GPTBot",[174,1229,1230],{},"PerplexityBot",[174,1232,1233],{},"ClaudeBot",[174,1235,1236],{},"Bytespider",[174,1238,1239],{},"Amazonbot",[174,1241,1242],{},"meta-externalagent",[479,1244,1245,1250,1253],{},[497,1246,1247],{},[185,1248,1249],{},"AI referral",[497,1251,1252],{},"Referrer is an AI engine, visitor is human",[497,1254,1255,1056,1258,1056,1261],{},[174,1256,1257],{},"perplexity.ai",[174,1259,1260],{},"chatgpt.com",[174,1262,1263],{},"claude.ai",[479,1265,1266,1270,1273],{},[497,1267,1268],{},[185,1269,199],{},[497,1271,1272],{},"Anonymized ~2% of everything else (Worker only)",[497,1274,1275],{},"the weighted denominator for AI-share metrics",[479,1277,1278,1284,1287],{},[497,1279,1280],{},[1281,1282,1283],"em",{},"(dropped)",[497,1285,1286],{},"The remaining non-AI traffic",[497,1288,1289],{},"never leaves your zone",[170,1291,1292],{},"The full bot and referrer lists are maintained on TrustData's side and synced into the Worker every few hours, so a new AI crawler is covered automatically with no redeploy. Over Logpush, coverage is retroactive only for the traffic your filter forwards (see the Logpush tab).",[1191,1294],{},[205,1296,1298],{"id":1297},"viewing-crawler-activity","Viewing crawler activity",[170,1300,1301,1302,1304],{},"Crawler events surface in the ",[185,1303,1170],{}," view for your attribution ID, one row per hit:",[179,1306,1307,1313,1318],{},[182,1308,1309,1310,1312],{},"Rows with an ",[185,1311,1174],{}," badge, where the user agent matched a known AI crawler",[182,1314,1309,1315,1317],{},[185,1316,1249],{}," badge, where a human visitor arrived from an AI engine",[182,1319,1320,1321,1324],{},"Any other event with a small ",[185,1322,1323],{},"bot"," tag, which is traffic the server flagged as non-human from the browser SDK",[170,1326,1327],{},"Live Events shows the last 30 minutes, refreshing every few seconds. Aggregated per-bot counts by day and page surface in your dashboard and refresh daily.",[1191,1329],{},[205,1331,1189],{"id":1332},"troubleshooting",[272,1334,1336],{"id":1335},"_401-unauthorized",[174,1337,1338],{},"401 Unauthorized",[179,1340,1341,1352,1362],{},[182,1342,1343,1344,1347,1348,1351],{},"Check the header is exactly ",[174,1345,1346],{},"X-API-Key: td_cf_..."," (no ",[174,1349,1350],{},"Bearer"," prefix)",[182,1353,1354,1355,1358,1359],{},"Verify the key is still ",[185,1356,1357],{},"Active"," under ",[185,1360,1361],{},"Organization → Integrations → Log ingest keys",[182,1363,1364],{},"Confirm no extra whitespace was added to the key when you entered it in the guided deploy form",[272,1366,1368],{"id":1367},"no-events-appear-in-the-dashboard","No events appear in the dashboard",[277,1370,1371,1378,1384,1394],{},[182,1372,1373,1374,1377],{},"Check the Worker is deployed and receiving traffic via its real-time logs: ",[185,1375,1376],{},"Workers & Pages → trustdata-ai-bot-collector → Logs → Begin log stream"," in the Cloudflare dashboard",[182,1379,1380,1381],{},"Confirm the UA matches a known bot by trying a curl with ",[174,1382,1383],{},"User-Agent: GPTBot/1.0",[182,1385,1386,1387,1389,1390],{},"Verify ",[174,1388,517],{}," is a real attribution ID UUID from ",[185,1391,525,1392,529],{},[219,1393,528],{},[182,1395,1396,1397,1399,1400,1402],{},"Check that ",[174,1398,501],{}," points to ",[174,1401,510],{}," (no trailing slash)",[272,1404,1406],{"id":1405},"events-arrive-in-live-events-but-aggregate-dashboards-lag","Events arrive in Live Events but aggregate dashboards lag",[170,1408,1409],{},"Live Events is real-time. The aggregated per-day / per-page bot dashboards refresh once a day (around 3:00 AM UTC), so those break­downs lag by one run. If it's been longer than 24 hours, contact support.",[272,1411,1413],{"id":1412},"worker-causes-latency-on-the-customer-response","Worker causes latency on the customer response",[170,1415,1416,1417,1420,1421,1424,1425,1427],{},"It shouldn't, because the Worker uses ",[174,1418,1419],{},"ctx.waitUntil()"," to fire-and-forget the TrustData POST after returning the origin response. If you see added latency, check the Worker's real-time ",[185,1422,1423],{},"Logs"," in the Cloudflare dashboard for an errored forward. Transient ingest failures are swallowed, but a bad ",[174,1426,501],{}," can cause DNS resolution delays.",[1191,1429],{},[205,1431,1433],{"id":1432},"webmcp-hosting-automatic","WebMCP hosting (automatic)",[170,1435,1436,1437,1442,1443,1446],{},"Once deployed, the same Worker also hosts your ",[350,1438,1441],{"href":1439,"rel":1440},"https://www.w3.org/TR/webmcp/",[354],"WebMCP"," manifest at ",[174,1444,1445],{},"/.well-known/webmcp.json",". AI agents read this file to discover which tools your site exposes (search, add-to-cart, booking, contact…) before loading any page.",[170,1448,1449],{},"You don't need a separate build step. TrustData serves the signed manifest and the Worker caches it on the edge.",[272,1451,1453],{"id":1452},"how-the-manifest-is-served","How the manifest is served",[277,1455,1456,1462,1469,1475,1485],{},[182,1457,1458,1459],{},"Agent requests ",[174,1460,1461],{},"https://\u003Cyour-zone>/.well-known/webmcp.json",[182,1463,1464,1465,1468],{},"Worker checks Cloudflare KV for a cached copy (",[174,1466,1467],{},"webmcp:v1:\u003Cattribution_id>",", 1-hour TTL)",[182,1470,1471,1472,1474],{},"On cache miss, Worker fetches from ",[174,1473,571],{}," + your attribution ID",[182,1476,1477,1478,1481,1482],{},"Response is returned with ",[174,1479,1480],{},"Content-Type: application/json"," and ",[174,1483,1484],{},"Cache-Control: public, max-age=3600",[182,1486,1487],{},"Agent verifies the Ed25519 signature inside the JSON body and calls the declared tools",[272,1489,1491],{"id":1490},"enable-it","Enable it",[170,1493,1494,1495,686],{},"WebMCP hosting is on by default in ",[174,1496,1497],{},"wrangler.jsonc",[210,1499,1503],{"className":1500,"code":1501,"language":1502,"meta":215,"style":215},"language-jsonc shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\"vars\": {\n  \"TRUSTDATA_MANIFEST_URL\": \"https://app.trustdata.tech/api/v1/webmcp\",\n  \"TRUSTDATA_ATTRIBUTION_ID\": \"\u003Cyour property UUID>\"\n},\n\"kv_namespaces\": [\n  { \"binding\": \"WEBMCP_CACHE\", \"id\": \"\u003Cyour KV namespace id>\" }\n]\n","jsonc",[174,1504,1505,1510,1515,1520,1525,1530,1535],{"__ignoreMap":215},[219,1506,1507],{"class":221,"line":222},[219,1508,1509],{},"\"vars\": {\n",[219,1511,1512],{"class":221,"line":228},[219,1513,1514],{},"  \"TRUSTDATA_MANIFEST_URL\": \"https://app.trustdata.tech/api/v1/webmcp\",\n",[219,1516,1517],{"class":221,"line":234},[219,1518,1519],{},"  \"TRUSTDATA_ATTRIBUTION_ID\": \"\u003Cyour property UUID>\"\n",[219,1521,1522],{"class":221,"line":240},[219,1523,1524],{},"},\n",[219,1526,1527],{"class":221,"line":246},[219,1528,1529],{},"\"kv_namespaces\": [\n",[219,1531,1532],{"class":221,"line":252},[219,1533,1534],{},"  { \"binding\": \"WEBMCP_CACHE\", \"id\": \"\u003Cyour KV namespace id>\" }\n",[219,1536,1537],{"class":221,"line":258},[219,1538,981],{},[170,1540,593,1541,1543,1544,1546,1547,1550],{},[185,1542,361],{}," button provisions this KV namespace automatically and writes its ID into ",[174,1545,1497],{},", so there's nothing to create by hand. To add or change the binding later, use ",[185,1548,1549],{},"Workers & Pages → trustdata-ai-bot-collector → Settings → Bindings"," in the Cloudflare dashboard.",[272,1552,1554],{"id":1553},"declare-the-tools","Declare the tools",[170,1556,1557,1558,1561,1562,1565,1566,1568],{},"In TrustData, go to ",[185,1559,1560],{},"Settings"," → ",[185,1563,1564],{},"Attribution Properties"," → your property → ",[185,1567,1441],{}," and add 2–3 tools:",[179,1570,1571,1580,1588],{},[182,1572,1573,1576,1577],{},[174,1574,1575],{},"search_products",", input schema: ",[174,1578,1579],{},"{ query: string }",[182,1581,1582,1576,1585],{},[174,1583,1584],{},"add_to_cart",[174,1586,1587],{},"{ sku: string, quantity: number }",[182,1589,1590,1576,1593],{},[174,1591,1592],{},"contact_sales",[174,1594,1595],{},"{ email: string, message: string }",[170,1597,1598,1599,1602],{},"Save. On the next Worker cache miss (at most 1 hour later), agents will see your updated manifest. Click ",[185,1600,1601],{},"Rotate keys"," to invalidate every cached signature immediately, which is useful if you suspect a leaked key.",[272,1604,1606],{"id":1605},"disable-webmcp-hosting","Disable WebMCP hosting",[170,1608,1609,1610,1613,1614,1616,1617,1619],{},"Remove the ",[174,1611,1612],{},"kv_namespaces"," block and set ",[174,1615,571],{}," to an empty string. The Worker falls through to your origin for ",[174,1618,1445],{},", so any existing static file you serve there keeps working.",[1191,1621],{},[170,1623,1624,1629,1630],{},[350,1625,1628],{"href":1626,"rel":1627},"https://trustdata.tech/product/integrations",[354],"Integrations overview"," on trustdata.tech · ",[350,1631,1634],{"href":1632,"rel":1633},"https://trustdata.tech/waitlist",[354],"Free trial",[1636,1637,1638],"style",{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}",{"title":215,"searchDepth":228,"depth":228,"links":1640},[1641,1642,1647,1648,1649,1655],{"id":207,"depth":228,"text":208},{"id":270,"depth":228,"text":137,"children":1643},[1644,1645,1646],{"id":274,"depth":234,"text":275},{"id":322,"depth":234,"text":323},{"id":1119,"depth":234,"text":1120},{"id":1195,"depth":228,"text":1196},{"id":1297,"depth":228,"text":1298},{"id":1332,"depth":228,"text":1189,"children":1650},[1651,1652,1653,1654],{"id":1335,"depth":234,"text":1338},{"id":1367,"depth":234,"text":1368},{"id":1405,"depth":234,"text":1406},{"id":1412,"depth":234,"text":1413},{"id":1432,"depth":228,"text":1433,"children":1656},[1657,1658,1659,1660],{"id":1452,"depth":234,"text":1453},{"id":1490,"depth":234,"text":1491},{"id":1553,"depth":234,"text":1554},{"id":1605,"depth":234,"text":1606},"Capture AI-bot visits and AI-engine referrals at the Cloudflare edge, traffic the browser SDK can't see.","md",null,{},true,{"title":55,"description":1661},"t6db-djwM8V6E4RBZRc1XmjmeXSRljT0FCssCPIyNxE",[1669,1671],{"title":30,"path":52,"stem":53,"description":1670,"children":-1},"Connect your ad platforms into one unified data layer, with no more conflicting reports.",{"title":59,"path":60,"stem":61,"description":1672,"children":-1},"Connect Google Ads and configure tracking parameters.",1781720350158]