{"_id":"@apideck/agent-analytics","_rev":"21-cdec942b4770a153dd6b185d57952d65","name":"@apideck/agent-analytics","dist-tags":{"latest":"0.17.0"},"versions":{"0.1.0":{"name":"@apideck/agent-analytics","version":"0.1.0","keywords":["ai","agents","analytics","bot-detection","claude","chatgpt","perplexity","llm","posthog","nextjs","vercel","middleware"],"author":{"name":"Apideck"},"license":"MIT","_id":"@apideck/agent-analytics@0.1.0","maintainers":[{"name":"gdewilde","email":"gertjan@apideck.com"},{"name":"nicklloyd","email":"nick@apideck.com"},{"name":"ritiksingh7","email":"ritik@apideck.com"},{"name":"samzani","email":"samir.amzani@gmail.com"},{"name":"lagoni","email":"jonas-lt@live.dk"},{"name":"jakeprins","email":"jake@apideck.com"},{"name":"gmenoiaa","email":"gmenoiaa@gmail.com"}],"homepage":"https://github.com/apideck-libraries/agent-analytics#readme","bugs":{"url":"https://github.com/apideck-libraries/agent-analytics/issues"},"dist":{"shasum":"27d87926d64792a94a5935b013b8ae041215da09","tarball":"https://registry.npmjs.org/@apideck/agent-analytics/-/agent-analytics-0.1.0.tgz","fileCount":29,"integrity":"sha512-8r8/EF9/aTLTllfgHzUU/LJpgWd8Hb572XXfNTD86J7IdyzXOul7tlQarkIErGMPF5IMb3No1Kq+Mie93lLDUg==","signatures":[{"sig":"MEUCIDNIcCPzvm6Jt9ygj0ghedHN9GLSOjsFffjhRPXz2DPdAiEA081vlJJ82Q3jUN/whvA687+WnFlnWcvkpZtUrPngpeQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":115731},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./posthog":{"types":"./dist/adapters/posthog.d.ts","import":"./dist/adapters/posthog.js","require":"./dist/adapters/posthog.cjs"},"./webhook":{"types":"./dist/adapters/webhook.d.ts","import":"./dist/adapters/webhook.js","require":"./dist/adapters/webhook.cjs"},"./markdown":{"types":"./dist/markdown.d.ts","import":"./dist/markdown.js","require":"./dist/markdown.cjs"}},"gitHead":"8e53907aac383eaaa2ac7f77b3e34d7e863d91d2","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"gdewilde","email":"gertjan@apideck.com"},"repository":{"url":"git+https://github.com/apideck-libraries/agent-analytics.git","type":"git"},"_npmVersion":"10.7.0","description":"Track AI agent and bot traffic to your Next.js / Vercel app — PostHog, webhooks, or any custom analytics backend. Detects Claude, ChatGPT, Perplexity, Google-Extended, and more.","directories":{},"_nodeVersion":"20.15.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0","@types/node":"^20.14.0"},"_npmOperationalInternal":{"tmp":"tmp/agent-analytics_0.1.0_1776582018894_0.9600718745247194","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@apideck/agent-analytics","version":"0.1.1","keywords":["ai","agents","analytics","bot-detection","claude","chatgpt","perplexity","llm","posthog","nextjs","vercel","middleware"],"author":{"name":"Apideck"},"license":"MIT","_id":"@apideck/agent-analytics@0.1.1","maintainers":[{"name":"gdewilde","email":"gertjan@apideck.com"},{"name":"nicklloyd","email":"nick@apideck.com"},{"name":"ritiksingh7","email":"ritik@apideck.com"},{"name":"samzani","email":"samir.amzani@gmail.com"},{"name":"lagoni","email":"jonas-lt@live.dk"},{"name":"jakeprins","email":"jake@apideck.com"},{"name":"gmenoiaa","email":"gmenoiaa@gmail.com"}],"homepage":"https://github.com/apideck-libraries/agent-analytics#readme","bugs":{"url":"https://github.com/apideck-libraries/agent-analytics/issues"},"dist":{"shasum":"2d58093bf3a5c83eb6995a77026245367bd13fd4","tarball":"https://registry.npmjs.org/@apideck/agent-analytics/-/agent-analytics-0.1.1.tgz","fileCount":29,"integrity":"sha512-vX8nm+2XcFrDMGLXPkDRmEulvJjtxmFWTyMuRmsPOML/eEeP6sof6NV8kMkzVco5vhX0OpXVY9t9YmwNfah74Q==","signatures":[{"sig":"MEUCIQDdkGDD1fXcfm5AEXTzmNzlDBAuTAB71XQXmXk+fBw1FAIgN+YDDS71pBPv3p2yKP4YB79wFviOmwIUvw7EaMs2ltQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@apideck%2fagent-analytics@0.1.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":116922},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./posthog":{"types":"./dist/adapters/posthog.d.ts","import":"./dist/adapters/posthog.js","require":"./dist/adapters/posthog.cjs"},"./webhook":{"types":"./dist/adapters/webhook.d.ts","import":"./dist/adapters/webhook.js","require":"./dist/adapters/webhook.cjs"},"./markdown":{"types":"./dist/markdown.d.ts","import":"./dist/markdown.js","require":"./dist/markdown.cjs"}},"gitHead":"279b6f36c39a84e2c0af87f46c19012c721d5f71","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:3c6219ea-8471-4bed-b56d-4ce135c60b95"}},"repository":{"url":"git+https://github.com/apideck-libraries/agent-analytics.git","type":"git"},"_npmVersion":"11.12.1","description":"Track AI agent and bot traffic to your Next.js / Vercel app — PostHog, webhooks, or any custom analytics backend. Detects Claude, ChatGPT, Perplexity, Google-Extended, and more.","directories":{},"_nodeVersion":"22.22.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0","@types/node":"^20.14.0"},"_npmOperationalInternal":{"tmp":"tmp/agent-analytics_0.1.1_1776585843951_0.27990750235382356","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@apideck/agent-analytics","version":"0.2.0","keywords":["ai","agents","analytics","bot-detection","claude","chatgpt","perplexity","llm","posthog","nextjs","vercel","middleware"],"author":{"name":"Apideck"},"license":"MIT","_id":"@apideck/agent-analytics@0.2.0","maintainers":[{"name":"gdewilde","email":"gertjan@apideck.com"},{"name":"nicklloyd","email":"nick@apideck.com"},{"name":"ritiksingh7","email":"ritik@apideck.com"},{"name":"samzani","email":"samir.amzani@gmail.com"},{"name":"lagoni","email":"jonas-lt@live.dk"},{"name":"jakeprins","email":"jake@apideck.com"},{"name":"gmenoiaa","email":"gmenoiaa@gmail.com"}],"homepage":"https://github.com/apideck-libraries/agent-analytics#readme","bugs":{"url":"https://github.com/apideck-libraries/agent-analytics/issues"},"dist":{"shasum":"da12fab74b74c6d27373dc8f23d8716116fa7276","tarball":"https://registry.npmjs.org/@apideck/agent-analytics/-/agent-analytics-0.2.0.tgz","fileCount":29,"integrity":"sha512-kHsMObXwrHI33phAuxySMB50mGycxKpS1humF12vast06NzQT6j4Nbl51thHVn8/i2b319c7+rROcKiFjYyjbQ==","signatures":[{"sig":"MEUCIQDxqzt+kmrNDujF/TT+CnztIj9XLyt3ob282ZJrZZfWCQIgZ9Ta8vhueomIIGIZV4AMRld7bmLeLBnQKSJkMJr4pp8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@apideck%2fagent-analytics@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":148992},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./posthog":{"types":"./dist/adapters/posthog.d.ts","import":"./dist/adapters/posthog.js","require":"./dist/adapters/posthog.cjs"},"./webhook":{"types":"./dist/adapters/webhook.d.ts","import":"./dist/adapters/webhook.js","require":"./dist/adapters/webhook.cjs"},"./markdown":{"types":"./dist/markdown.d.ts","import":"./dist/markdown.js","require":"./dist/markdown.cjs"}},"gitHead":"9e64ac93f367c8a3914456f856d52ec0e00e905e","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:3c6219ea-8471-4bed-b56d-4ce135c60b95"}},"repository":{"url":"git+https://github.com/apideck-libraries/agent-analytics.git","type":"git"},"_npmVersion":"11.12.1","description":"Track AI agent and bot traffic to your Next.js / Vercel app — PostHog, webhooks, or any custom analytics backend. Detects Claude, ChatGPT, Perplexity, Google-Extended, and more.","directories":{},"_nodeVersion":"22.22.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0","@types/node":"^20.14.0"},"_npmOperationalInternal":{"tmp":"tmp/agent-analytics_0.2.0_1776587479634_0.8795239475642316","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@apideck/agent-analytics","version":"0.3.0","keywords":["ai","agents","analytics","bot-detection","claude","chatgpt","perplexity","llm","posthog","nextjs","vercel","middleware"],"author":{"name":"Apideck"},"license":"MIT","_id":"@apideck/agent-analytics@0.3.0","maintainers":[{"name":"gdewilde","email":"gertjan@apideck.com"},{"name":"nicklloyd","email":"nick@apideck.com"},{"name":"ritiksingh7","email":"ritik@apideck.com"},{"name":"samzani","email":"samir.amzani@gmail.com"},{"name":"lagoni","email":"jonas-lt@live.dk"},{"name":"jakeprins","email":"jake@apideck.com"},{"name":"gmenoiaa","email":"gmenoiaa@gmail.com"}],"homepage":"https://github.com/apideck-libraries/agent-analytics#readme","bugs":{"url":"https://github.com/apideck-libraries/agent-analytics/issues"},"dist":{"shasum":"7e1cbc6c1321246d25edd81bfcc1963770058c7a","tarball":"https://registry.npmjs.org/@apideck/agent-analytics/-/agent-analytics-0.3.0.tgz","fileCount":29,"integrity":"sha512-kjsrbUhuupBmMnB6MUOGMTvzez2NXyN73zE3ibRjSQ4FZZYkKXPTjN/x/NnXRluqanFHkRNqTstyG4P0EyXEJw==","signatures":[{"sig":"MEUCIE91ilEJsqNYytqZjMqZzlclttT6rr6znVh8hHHxrXY+AiEAxMJM2t8CoNX7VkUN47wfrS0QQyk96Y1Qk9fPi3Ez8hU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@apideck%2fagent-analytics@0.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":148918},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./posthog":{"types":"./dist/adapters/posthog.d.ts","import":"./dist/adapters/posthog.js","require":"./dist/adapters/posthog.cjs"},"./webhook":{"types":"./dist/adapters/webhook.d.ts","import":"./dist/adapters/webhook.js","require":"./dist/adapters/webhook.cjs"},"./markdown":{"types":"./dist/markdown.d.ts","import":"./dist/markdown.js","require":"./dist/markdown.cjs"}},"gitHead":"4ae978144a4ded6f503d20a2995c7a78e6c38136","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:3c6219ea-8471-4bed-b56d-4ce135c60b95"}},"repository":{"url":"git+https://github.com/apideck-libraries/agent-analytics.git","type":"git"},"_npmVersion":"11.12.1","description":"Track AI agent and bot traffic to your Next.js / Vercel app — PostHog, webhooks, or any custom analytics backend. Detects Claude, ChatGPT, Perplexity, Google-Extended, and more.","directories":{},"_nodeVersion":"22.22.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0","@types/node":"^20.14.0"},"_npmOperationalInternal":{"tmp":"tmp/agent-analytics_0.3.0_1776588253821_0.5509574811945701","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@apideck/agent-analytics","version":"0.4.0","keywords":["ai","agents","analytics","bot-detection","claude","chatgpt","perplexity","llm","posthog","nextjs","vercel","middleware"],"author":{"name":"Apideck"},"license":"MIT","_id":"@apideck/agent-analytics@0.4.0","maintainers":[{"name":"gdewilde","email":"gertjan@apideck.com"},{"name":"nicklloyd","email":"nick@apideck.com"},{"name":"ritiksingh7","email":"ritik@apideck.com"},{"name":"samzani","email":"samir.amzani@gmail.com"},{"name":"lagoni","email":"jonas-lt@live.dk"},{"name":"jakeprins","email":"jake@apideck.com"},{"name":"gmenoiaa","email":"gmenoiaa@gmail.com"}],"homepage":"https://github.com/apideck-libraries/agent-analytics#readme","bugs":{"url":"https://github.com/apideck-libraries/agent-analytics/issues"},"dist":{"shasum":"be4ed28fc5fd5050a86df72241f07e6e468f8fbd","tarball":"https://registry.npmjs.org/@apideck/agent-analytics/-/agent-analytics-0.4.0.tgz","fileCount":29,"integrity":"sha512-mmGa8RTOlDu1/Io2Y0Ow0rL/GYlwnXs3LcmkIjvpLVESay5BqvVL9xdPwoHWZv1RaLFv4v/DKPz7oom1WfQCkg==","signatures":[{"sig":"MEQCIHZ6+9OURCn9Hm1ihQPRZgm1sPIdQCZ+2sjbtGI+K32SAiAyCUVKr1XFGceWF4kW+egU3xZLw1V3uWMpuSQsjUpQ/Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@apideck%2fagent-analytics@0.4.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":149651},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./posthog":{"types":"./dist/adapters/posthog.d.ts","import":"./dist/adapters/posthog.js","require":"./dist/adapters/posthog.cjs"},"./webhook":{"types":"./dist/adapters/webhook.d.ts","import":"./dist/adapters/webhook.js","require":"./dist/adapters/webhook.cjs"},"./markdown":{"types":"./dist/markdown.d.ts","import":"./dist/markdown.js","require":"./dist/markdown.cjs"}},"gitHead":"4e6a6bbba0b0a7988cca46cebe6477485ce2f9b3","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:3c6219ea-8471-4bed-b56d-4ce135c60b95"}},"repository":{"url":"git+https://github.com/apideck-libraries/agent-analytics.git","type":"git"},"_npmVersion":"11.12.1","description":"Track AI agent and bot traffic to your Next.js / Vercel app — PostHog, webhooks, or any custom analytics backend. Detects Claude, ChatGPT, Perplexity, Google-Extended, and more.","directories":{},"_nodeVersion":"22.22.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0","@types/node":"^20.14.0"},"_npmOperationalInternal":{"tmp":"tmp/agent-analytics_0.4.0_1776725345821_0.35070543250554165","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"@apideck/agent-analytics","version":"0.5.0","keywords":["ai","agents","analytics","bot-detection","claude","chatgpt","perplexity","llm","posthog","nextjs","vercel","middleware"],"author":{"name":"Apideck"},"license":"MIT","_id":"@apideck/agent-analytics@0.5.0","maintainers":[{"name":"gdewilde","email":"gertjan@apideck.com"},{"name":"nicklloyd","email":"nick@apideck.com"},{"name":"ritiksingh7","email":"ritik@apideck.com"},{"name":"samzani","email":"samir.amzani@gmail.com"},{"name":"lagoni","email":"jonas-lt@live.dk"},{"name":"jakeprins","email":"jake@apideck.com"},{"name":"gmenoiaa","email":"gmenoiaa@gmail.com"}],"homepage":"https://github.com/apideck-libraries/agent-analytics#readme","bugs":{"url":"https://github.com/apideck-libraries/agent-analytics/issues"},"dist":{"shasum":"32e154bbe0215492b43eb93a42a0c418967a94ed","tarball":"https://registry.npmjs.org/@apideck/agent-analytics/-/agent-analytics-0.5.0.tgz","fileCount":29,"integrity":"sha512-TOqEqRSBSWnWKEZ+r8SOSFE5ErDuEWkavCJWlInGIbTD06/vvnBwerFHqvbvaL/IS90A90l8l5qtTuHiJ3J3zw==","signatures":[{"sig":"MEYCIQCspOnPxoJgkfGZGvKIwLXyOiJPz/qIJnoCRvDzlWykvgIhAOhFTGH9Cj50a4v73UF9O2UvxAzt7CCmvG+ayUtUDI0C","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@apideck%2fagent-analytics@0.5.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":151021},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./posthog":{"types":"./dist/adapters/posthog.d.ts","import":"./dist/adapters/posthog.js","require":"./dist/adapters/posthog.cjs"},"./webhook":{"types":"./dist/adapters/webhook.d.ts","import":"./dist/adapters/webhook.js","require":"./dist/adapters/webhook.cjs"},"./markdown":{"types":"./dist/markdown.d.ts","import":"./dist/markdown.js","require":"./dist/markdown.cjs"}},"gitHead":"2cc8b013eae1b08086b3d686ecb439a94bad5dd7","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:3c6219ea-8471-4bed-b56d-4ce135c60b95"}},"repository":{"url":"git+https://github.com/apideck-libraries/agent-analytics.git","type":"git"},"_npmVersion":"11.12.1","description":"Track AI agent and bot traffic to your Next.js / Vercel app — PostHog, webhooks, or any custom analytics backend. Detects Claude, ChatGPT, Perplexity, Google-Extended, and more.","directories":{},"_nodeVersion":"22.22.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0","@types/node":"^20.14.0"},"_npmOperationalInternal":{"tmp":"tmp/agent-analytics_0.5.0_1776729210136_0.6287821875064408","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"@apideck/agent-analytics","version":"0.6.0","keywords":["ai","agents","analytics","bot-detection","claude","chatgpt","perplexity","llm","posthog","nextjs","vercel","middleware"],"author":{"name":"Apideck"},"license":"MIT","_id":"@apideck/agent-analytics@0.6.0","maintainers":[{"name":"gdewilde","email":"gertjan@apideck.com"},{"name":"nicklloyd","email":"nick@apideck.com"},{"name":"ritiksingh7","email":"ritik@apideck.com"},{"name":"samzani","email":"samir.amzani@gmail.com"},{"name":"lagoni","email":"jonas-lt@live.dk"},{"name":"jakeprins","email":"jake@apideck.com"},{"name":"gmenoiaa","email":"gmenoiaa@gmail.com"}],"homepage":"https://github.com/apideck-libraries/agent-analytics#readme","bugs":{"url":"https://github.com/apideck-libraries/agent-analytics/issues"},"dist":{"shasum":"640241d0d613a6a0dc176c5cb539dbafc3cff21e","tarball":"https://registry.npmjs.org/@apideck/agent-analytics/-/agent-analytics-0.6.0.tgz","fileCount":29,"integrity":"sha512-4oW9W46L2OcUxte9R6Z+wcJRZrvHNLleVvXDR5prbPJ+6fJNaVPcrDsVkbIwetw8aS6RCmyOi0cu0AkwbxSAmw==","signatures":[{"sig":"MEYCIQCIKbnYdqEbhMe1vYtZqDUeJ+EIxzhhDb1igoCbwVOmQAIhAMck+7fKY3V0w+mWHarjlYA6+ke+rqD2RNQTHpWFIHJK","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@apideck%2fagent-analytics@0.6.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":166491},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./posthog":{"types":"./dist/adapters/posthog.d.ts","import":"./dist/adapters/posthog.js","require":"./dist/adapters/posthog.cjs"},"./webhook":{"types":"./dist/adapters/webhook.d.ts","import":"./dist/adapters/webhook.js","require":"./dist/adapters/webhook.cjs"},"./markdown":{"types":"./dist/markdown.d.ts","import":"./dist/markdown.js","require":"./dist/markdown.cjs"}},"gitHead":"3dbeeb7f0ca780694bb271bc58cbc08a3acbafd7","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:3c6219ea-8471-4bed-b56d-4ce135c60b95"}},"repository":{"url":"git+https://github.com/apideck-libraries/agent-analytics.git","type":"git"},"_npmVersion":"11.12.1","description":"Track AI agent and bot traffic to your Next.js / Vercel app — PostHog, webhooks, or any custom analytics backend. Detects Claude, ChatGPT, Perplexity, Google-Extended, and more.","directories":{},"_nodeVersion":"22.22.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0","@types/node":"^20.14.0"},"_npmOperationalInternal":{"tmp":"tmp/agent-analytics_0.6.0_1776745796748_0.44715159289241324","host":"s3://npm-registry-packages-npm-production"}},"0.7.0":{"name":"@apideck/agent-analytics","version":"0.7.0","keywords":["ai","agents","analytics","bot-detection","claude","chatgpt","perplexity","llm","posthog","nextjs","vercel","middleware"],"author":{"name":"Apideck"},"license":"MIT","_id":"@apideck/agent-analytics@0.7.0","maintainers":[{"name":"gdewilde","email":"gertjan@apideck.com"},{"name":"nicklloyd","email":"nick@apideck.com"},{"name":"ritiksingh7","email":"ritik@apideck.com"},{"name":"samzani","email":"samir.amzani@gmail.com"},{"name":"lagoni","email":"jonas-lt@live.dk"},{"name":"jakeprins","email":"jake@apideck.com"},{"name":"gmenoiaa","email":"gmenoiaa@gmail.com"}],"homepage":"https://github.com/apideck-libraries/agent-analytics#readme","bugs":{"url":"https://github.com/apideck-libraries/agent-analytics/issues"},"dist":{"shasum":"5f0e62e5b49875b3e7f6a9d18b90aea0e028e0a1","tarball":"https://registry.npmjs.org/@apideck/agent-analytics/-/agent-analytics-0.7.0.tgz","fileCount":29,"integrity":"sha512-MvRNyNLOf7E9FGhIielJ2y6GKPuswp9Ves3jSRDCK38jUIkCVwtjYP7cceSvKGABzyCxc9XzJZKJ8zmc2zSisA==","signatures":[{"sig":"MEUCIQCsuhnwpgdXbHuZojNozY3aQYaVP9RTmw0ngqkF+6U9ZQIgMpdXX7Km1a2IEfIgXIuCJkQ2ybHUG2dBM9hsPCerM8w=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@apideck%2fagent-analytics@0.7.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":188160},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./posthog":{"types":"./dist/adapters/posthog.d.ts","import":"./dist/adapters/posthog.js","require":"./dist/adapters/posthog.cjs"},"./webhook":{"types":"./dist/adapters/webhook.d.ts","import":"./dist/adapters/webhook.js","require":"./dist/adapters/webhook.cjs"},"./markdown":{"types":"./dist/markdown.d.ts","import":"./dist/markdown.js","require":"./dist/markdown.cjs"}},"gitHead":"fbf9298e144d39e3bfb99fed141f769d1749ed18","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:3c6219ea-8471-4bed-b56d-4ce135c60b95"}},"repository":{"url":"git+https://github.com/apideck-libraries/agent-analytics.git","type":"git"},"_npmVersion":"11.13.0","description":"Track AI agent and bot traffic to your Next.js / Vercel app — PostHog, webhooks, or any custom analytics backend. Detects Claude, ChatGPT, Perplexity, Google-Extended, and more.","directories":{},"_nodeVersion":"22.22.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0","@types/node":"^20.14.0"},"_npmOperationalInternal":{"tmp":"tmp/agent-analytics_0.7.0_1777234921539_0.5282472549010846","host":"s3://npm-registry-packages-npm-production"}},"0.8.0":{"name":"@apideck/agent-analytics","version":"0.8.0","keywords":["ai","agents","analytics","bot-detection","claude","chatgpt","perplexity","llm","posthog","nextjs","vercel","middleware"],"author":{"name":"Apideck"},"license":"MIT","_id":"@apideck/agent-analytics@0.8.0","maintainers":[{"name":"gdewilde","email":"gertjan@apideck.com"},{"name":"nicklloyd","email":"nick@apideck.com"},{"name":"ritiksingh7","email":"ritik@apideck.com"},{"name":"samzani","email":"samir.amzani@gmail.com"},{"name":"lagoni","email":"jonas-lt@live.dk"},{"name":"jakeprins","email":"jake@apideck.com"},{"name":"gmenoiaa","email":"gmenoiaa@gmail.com"}],"homepage":"https://github.com/apideck-libraries/agent-analytics#readme","bugs":{"url":"https://github.com/apideck-libraries/agent-analytics/issues"},"dist":{"shasum":"f8b1526de292c53e7b00e046515fd44152cd0a36","tarball":"https://registry.npmjs.org/@apideck/agent-analytics/-/agent-analytics-0.8.0.tgz","fileCount":29,"integrity":"sha512-zOgRUBpOfYyXMzlbHz1T0ZllQZb6Jj++ZDzBDFpjwXm4sXS/TnfAnEplVEnk1FlEU00eiIC6pKv7Fk2w2WkWnw==","signatures":[{"sig":"MEQCIECZC9s5TprVjOT0WTvOJNGnpUXZ1BDDvApcUheLJ38mAiAoBGMOwigsLbbUTkQBq1QPrfuJqUgvJ/DJHYAcGSq7JA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@apideck%2fagent-analytics@0.8.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":190602},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./posthog":{"types":"./dist/adapters/posthog.d.ts","import":"./dist/adapters/posthog.js","require":"./dist/adapters/posthog.cjs"},"./webhook":{"types":"./dist/adapters/webhook.d.ts","import":"./dist/adapters/webhook.js","require":"./dist/adapters/webhook.cjs"},"./markdown":{"types":"./dist/markdown.d.ts","import":"./dist/markdown.js","require":"./dist/markdown.cjs"}},"gitHead":"415573d0fe2d5bb7decbd32adf90d878adf02cc6","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:3c6219ea-8471-4bed-b56d-4ce135c60b95"}},"repository":{"url":"git+https://github.com/apideck-libraries/agent-analytics.git","type":"git"},"_npmVersion":"11.13.0","description":"Track AI agent and bot traffic to your Next.js / Vercel app — PostHog, webhooks, or any custom analytics backend. Detects Claude, ChatGPT, Perplexity, Google-Extended, and more.","directories":{},"_nodeVersion":"22.22.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0","@types/node":"^20.14.0"},"_npmOperationalInternal":{"tmp":"tmp/agent-analytics_0.8.0_1777234949968_0.6244476800610845","host":"s3://npm-registry-packages-npm-production"}},"0.9.0":{"name":"@apideck/agent-analytics","version":"0.9.0","keywords":["ai","agents","analytics","bot-detection","claude","chatgpt","perplexity","llm","posthog","nextjs","vercel","middleware"],"author":{"name":"Apideck"},"license":"MIT","_id":"@apideck/agent-analytics@0.9.0","maintainers":[{"name":"gdewilde","email":"gertjan@apideck.com"},{"name":"nicklloyd","email":"nick@apideck.com"},{"name":"ritiksingh7","email":"ritik@apideck.com"},{"name":"samzani","email":"samir.amzani@gmail.com"},{"name":"lagoni","email":"jonas-lt@live.dk"},{"name":"jakeprins","email":"jake@apideck.com"},{"name":"gmenoiaa","email":"gmenoiaa@gmail.com"}],"homepage":"https://github.com/apideck-libraries/agent-analytics#readme","bugs":{"url":"https://github.com/apideck-libraries/agent-analytics/issues"},"dist":{"shasum":"6ef993965d5332fee3998b6b948e9ac0eb584d3d","tarball":"https://registry.npmjs.org/@apideck/agent-analytics/-/agent-analytics-0.9.0.tgz","fileCount":29,"integrity":"sha512-Fn7lY5xiVhpxHx6cwl2qtNRmn5hdFuuLBTExkJ4Upy9cQ2+EBbw4Kta6Nd9cAJQXf9SdOOKcxiLkyCCYWwn+fQ==","signatures":[{"sig":"MEQCIFEp7uWlxiyi1/D/65J1ZMMoj8ij0C8nEQ8c2J1AvfZjAiBrvPXTLkt4ldPsu6bOJ9Wxo+YD5Qf/pi/sw6WFwjzzFw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@apideck%2fagent-analytics@0.9.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":200323},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./posthog":{"types":"./dist/adapters/posthog.d.ts","import":"./dist/adapters/posthog.js","require":"./dist/adapters/posthog.cjs"},"./webhook":{"types":"./dist/adapters/webhook.d.ts","import":"./dist/adapters/webhook.js","require":"./dist/adapters/webhook.cjs"},"./markdown":{"types":"./dist/markdown.d.ts","import":"./dist/markdown.js","require":"./dist/markdown.cjs"}},"gitHead":"f786ef7a911f6c75d586f0e733ecd160612983c1","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:3c6219ea-8471-4bed-b56d-4ce135c60b95"}},"repository":{"url":"git+https://github.com/apideck-libraries/agent-analytics.git","type":"git"},"_npmVersion":"11.13.0","description":"Track AI agent and bot traffic to your Next.js / Vercel app — PostHog, webhooks, or any custom analytics backend. Detects Claude, ChatGPT, Perplexity, Google-Extended, and more.","directories":{},"_nodeVersion":"22.22.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0","@types/node":"^20.14.0"},"_npmOperationalInternal":{"tmp":"tmp/agent-analytics_0.9.0_1777236868120_0.4517482009730287","host":"s3://npm-registry-packages-npm-production"}},"0.10.0":{"name":"@apideck/agent-analytics","version":"0.10.0","keywords":["ai","agents","analytics","bot-detection","claude","chatgpt","perplexity","llm","posthog","nextjs","vercel","middleware"],"author":{"name":"Apideck"},"license":"MIT","_id":"@apideck/agent-analytics@0.10.0","maintainers":[{"name":"gdewilde","email":"gertjan@apideck.com"},{"name":"nicklloyd","email":"nick@apideck.com"},{"name":"ritiksingh7","email":"ritik@apideck.com"},{"name":"samzani","email":"samir.amzani@gmail.com"},{"name":"lagoni","email":"jonas-lt@live.dk"},{"name":"jakeprins","email":"jake@apideck.com"},{"name":"gmenoiaa","email":"gmenoiaa@gmail.com"}],"homepage":"https://github.com/apideck-libraries/agent-analytics#readme","bugs":{"url":"https://github.com/apideck-libraries/agent-analytics/issues"},"dist":{"shasum":"44f90806eff220567442e3dec8e56435f7767fb4","tarball":"https://registry.npmjs.org/@apideck/agent-analytics/-/agent-analytics-0.10.0.tgz","fileCount":29,"integrity":"sha512-QMgFt66CZR5MK8qCuMrimNQc7/miP/emd7K63jOXZZuBrWFqiOLED2EKZzsRUlvTSqSe8t5FB56CBhTJNuO/yQ==","signatures":[{"sig":"MEYCIQCXo2lvhKI6pIGm3Ndf+Ck3JRLK5Zxc1gxVmgCW0mzyHAIhAJxXBQPfoHrHFH1q3Tw7ANQlSlZH9H1B4FsOfWe0cHxY","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@apideck%2fagent-analytics@0.10.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":209554},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./posthog":{"types":"./dist/adapters/posthog.d.ts","import":"./dist/adapters/posthog.js","require":"./dist/adapters/posthog.cjs"},"./webhook":{"types":"./dist/adapters/webhook.d.ts","import":"./dist/adapters/webhook.js","require":"./dist/adapters/webhook.cjs"},"./markdown":{"types":"./dist/markdown.d.ts","import":"./dist/markdown.js","require":"./dist/markdown.cjs"}},"gitHead":"61ed722a4d015ce30edfaf22042e874c5e477d54","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:3c6219ea-8471-4bed-b56d-4ce135c60b95"}},"repository":{"url":"git+https://github.com/apideck-libraries/agent-analytics.git","type":"git"},"_npmVersion":"12.0.2","description":"Track AI agent and bot traffic to your Next.js / Vercel app — PostHog, webhooks, or any custom analytics backend. Detects Claude, ChatGPT, Perplexity, Google-Extended, and more.","directories":{},"_nodeVersion":"22.23.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0","@types/node":"^20.14.0"},"_npmOperationalInternal":{"tmp":"tmp/agent-analytics_0.10.0_1785642825095_0.5292491929843144","host":"s3://npm-registry-packages-npm-production"}},"0.11.0":{"name":"@apideck/agent-analytics","version":"0.11.0","keywords":["ai","agents","analytics","bot-detection","claude","chatgpt","perplexity","llm","posthog","nextjs","vercel","middleware"],"author":{"name":"Apideck"},"license":"MIT","_id":"@apideck/agent-analytics@0.11.0","maintainers":[{"name":"gdewilde","email":"gertjan@apideck.com"},{"name":"nicklloyd","email":"nick@apideck.com"},{"name":"ritiksingh7","email":"ritik@apideck.com"},{"name":"samzani","email":"samir.amzani@gmail.com"},{"name":"lagoni","email":"jonas-lt@live.dk"},{"name":"jakeprins","email":"jake@apideck.com"},{"name":"gmenoiaa","email":"gmenoiaa@gmail.com"}],"homepage":"https://github.com/apideck-libraries/agent-analytics#readme","bugs":{"url":"https://github.com/apideck-libraries/agent-analytics/issues"},"dist":{"shasum":"84d92b17ba000cac3790c809322d742efae2cc9f","tarball":"https://registry.npmjs.org/@apideck/agent-analytics/-/agent-analytics-0.11.0.tgz","fileCount":29,"integrity":"sha512-olkAGqr6ZbeztjuYKuIf9F5pqPRMvaZr8giFeHw9nHmlsl9CH2x8vQgfKe+zAXQyy8IryI6MUkGsbpeMlSEO3g==","signatures":[{"sig":"MEYCIQCXCu9ACZzwPMV/HXsHSaWDKiHZP5RI2IAKYeYAyGyiqQIhAMfq2cQBpfiA3qEvMHK0XSN5giPqkdW0jV89KeazwQCv","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@apideck%2fagent-analytics@0.11.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":329860},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./posthog":{"types":"./dist/adapters/posthog.d.ts","import":"./dist/adapters/posthog.js","require":"./dist/adapters/posthog.cjs"},"./webhook":{"types":"./dist/adapters/webhook.d.ts","import":"./dist/adapters/webhook.js","require":"./dist/adapters/webhook.cjs"},"./markdown":{"types":"./dist/markdown.d.ts","import":"./dist/markdown.js","require":"./dist/markdown.cjs"}},"gitHead":"8364c745c377d55cc12cf070543c43590ef626c3","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:3c6219ea-8471-4bed-b56d-4ce135c60b95"}},"repository":{"url":"git+https://github.com/apideck-libraries/agent-analytics.git","type":"git"},"_npmVersion":"12.0.2","description":"Track AI agent and bot traffic to your Next.js / Vercel app — PostHog, webhooks, or any custom analytics backend. Detects Claude, ChatGPT, Perplexity, Google-Extended, and more.","directories":{},"_nodeVersion":"22.23.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0","@types/node":"^20.14.0"},"_npmOperationalInternal":{"tmp":"tmp/agent-analytics_0.11.0_1785644289159_0.6679745722914969","host":"s3://npm-registry-packages-npm-production"}},"0.12.0":{"name":"@apideck/agent-analytics","version":"0.12.0","keywords":["ai","agents","analytics","bot-detection","claude","chatgpt","perplexity","llm","posthog","nextjs","vercel","middleware"],"author":{"name":"Apideck"},"license":"MIT","_id":"@apideck/agent-analytics@0.12.0","maintainers":[{"name":"gdewilde","email":"gertjan@apideck.com"},{"name":"nicklloyd","email":"nick@apideck.com"},{"name":"ritiksingh7","email":"ritik@apideck.com"},{"name":"samzani","email":"samir.amzani@gmail.com"},{"name":"lagoni","email":"jonas-lt@live.dk"},{"name":"jakeprins","email":"jake@apideck.com"},{"name":"gmenoiaa","email":"gmenoiaa@gmail.com"}],"homepage":"https://github.com/apideck-libraries/agent-analytics#readme","bugs":{"url":"https://github.com/apideck-libraries/agent-analytics/issues"},"dist":{"shasum":"0864769c22339521b3675d871893c3324096fc7e","tarball":"https://registry.npmjs.org/@apideck/agent-analytics/-/agent-analytics-0.12.0.tgz","fileCount":35,"integrity":"sha512-53bqtNdtzdV3hgL5xU+DceQX/iIZe8IvQjYFupF940jNKo380YcffWBJ58XOq2NjDEXaVhmQgn6JBsIv8/roVw==","signatures":[{"sig":"MEYCIQCKOgXpCu4ZyPISh4QEK4y6wrVgXBX4OWWL0RCh9VfadQIhAJ6A944rDYUhgZXX+qquZKYoyjm0W2ZpJwJEoJyOikfb","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@apideck%2fagent-analytics@0.12.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":386785},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./verify":{"types":"./dist/verify.d.ts","import":"./dist/verify.js","require":"./dist/verify.cjs"},"./posthog":{"types":"./dist/adapters/posthog.d.ts","import":"./dist/adapters/posthog.js","require":"./dist/adapters/posthog.cjs"},"./webhook":{"types":"./dist/adapters/webhook.d.ts","import":"./dist/adapters/webhook.js","require":"./dist/adapters/webhook.cjs"},"./markdown":{"types":"./dist/markdown.d.ts","import":"./dist/markdown.js","require":"./dist/markdown.cjs"}},"gitHead":"231c0d291a515300a00fae09e1784e29ecd7cb54","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:3c6219ea-8471-4bed-b56d-4ce135c60b95"}},"repository":{"url":"git+https://github.com/apideck-libraries/agent-analytics.git","type":"git"},"_npmVersion":"12.0.2","description":"Track AI agent and bot traffic to your Next.js / Vercel app — PostHog, webhooks, or any custom analytics backend. Detects Claude, ChatGPT, Perplexity, Google-Extended, and more.","directories":{},"_nodeVersion":"22.23.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0","@types/node":"^20.14.0"},"_npmOperationalInternal":{"tmp":"tmp/agent-analytics_0.12.0_1785660139183_0.9271156275315391","host":"s3://npm-registry-packages-npm-production"}},"0.13.0":{"name":"@apideck/agent-analytics","version":"0.13.0","keywords":["ai","agents","analytics","bot-detection","claude","chatgpt","perplexity","llm","posthog","nextjs","vercel","middleware"],"author":{"name":"Apideck"},"license":"MIT","_id":"@apideck/agent-analytics@0.13.0","maintainers":[{"name":"gdewilde","email":"gertjan@apideck.com"},{"name":"nicklloyd","email":"nick@apideck.com"},{"name":"ritiksingh7","email":"ritik@apideck.com"},{"name":"samzani","email":"samir.amzani@gmail.com"},{"name":"lagoni","email":"jonas-lt@live.dk"},{"name":"jakeprins","email":"jake@apideck.com"},{"name":"gmenoiaa","email":"gmenoiaa@gmail.com"}],"homepage":"https://github.com/apideck-libraries/agent-analytics#readme","bugs":{"url":"https://github.com/apideck-libraries/agent-analytics/issues"},"dist":{"shasum":"1165713b339acf4e7646fac319137b16393a7b3c","tarball":"https://registry.npmjs.org/@apideck/agent-analytics/-/agent-analytics-0.13.0.tgz","fileCount":35,"integrity":"sha512-5Z2byMjpgc8rcHRT1s81T2IlXNdXerM/k4Y9vE/yP1ZqhzE60I4eOHbf7GV4tIJ3LqE/nk17ibHvEBALx3jyTw==","signatures":[{"sig":"MEUCIEo8XM7aSeRr7gNA+Q0Pu7bd+ru9tdS6hI6MxQvgtI6fAiEApJQkeAqTfbI2rqGhmfnEqPGKFs91hoFGMsr2zg8oGps=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@apideck%2fagent-analytics@0.13.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":415854},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./verify":{"types":"./dist/verify.d.ts","import":"./dist/verify.js","require":"./dist/verify.cjs"},"./posthog":{"types":"./dist/adapters/posthog.d.ts","import":"./dist/adapters/posthog.js","require":"./dist/adapters/posthog.cjs"},"./webhook":{"types":"./dist/adapters/webhook.d.ts","import":"./dist/adapters/webhook.js","require":"./dist/adapters/webhook.cjs"},"./markdown":{"types":"./dist/markdown.d.ts","import":"./dist/markdown.js","require":"./dist/markdown.cjs"}},"gitHead":"483706ba64f188599d8e20aa39d5144808b7014b","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:3c6219ea-8471-4bed-b56d-4ce135c60b95"}},"repository":{"url":"git+https://github.com/apideck-libraries/agent-analytics.git","type":"git"},"_npmVersion":"12.0.2","description":"Track AI agent and bot traffic to your Next.js / Vercel app — PostHog, webhooks, or any custom analytics backend. Detects Claude, ChatGPT, Perplexity, Google-Extended, and more.","directories":{},"_nodeVersion":"22.23.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0","@types/node":"^20.14.0"},"_npmOperationalInternal":{"tmp":"tmp/agent-analytics_0.13.0_1785660364180_0.4301537316010413","host":"s3://npm-registry-packages-npm-production"}},"0.14.0":{"name":"@apideck/agent-analytics","version":"0.14.0","keywords":["ai","agents","analytics","bot-detection","claude","chatgpt","perplexity","llm","posthog","nextjs","vercel","middleware"],"author":{"name":"Apideck"},"license":"MIT","_id":"@apideck/agent-analytics@0.14.0","maintainers":[{"name":"gdewilde","email":"gertjan@apideck.com"},{"name":"nicklloyd","email":"nick@apideck.com"},{"name":"ritiksingh7","email":"ritik@apideck.com"},{"name":"samzani","email":"samir.amzani@gmail.com"},{"name":"lagoni","email":"jonas-lt@live.dk"},{"name":"jakeprins","email":"jake@apideck.com"},{"name":"gmenoiaa","email":"gmenoiaa@gmail.com"}],"homepage":"https://github.com/apideck-libraries/agent-analytics#readme","bugs":{"url":"https://github.com/apideck-libraries/agent-analytics/issues"},"dist":{"shasum":"f0e5600ceec855142627b70adc48537bbc7d11c3","tarball":"https://registry.npmjs.org/@apideck/agent-analytics/-/agent-analytics-0.14.0.tgz","fileCount":35,"integrity":"sha512-anP7tgS9tNvdpbhCGRWfm9NVlAgZTnxP1F2BFd01rrH6/2yFWg0rDW1nzpFOxAQYCPN8St3Dm4QC+nfof1uJuA==","signatures":[{"sig":"MEYCIQDfI8ahRl1Zd/iCFQ1mSpJl1eyB7r39J3cwTqIAGv5T6QIhALjHxysWcUCXUdLlJ/IP4jMgdSYwm4bEg4dvPHjjFCpb","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@apideck%2fagent-analytics@0.14.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":486470},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./verify":{"types":"./dist/verify.d.ts","import":"./dist/verify.js","require":"./dist/verify.cjs"},"./posthog":{"types":"./dist/adapters/posthog.d.ts","import":"./dist/adapters/posthog.js","require":"./dist/adapters/posthog.cjs"},"./webhook":{"types":"./dist/adapters/webhook.d.ts","import":"./dist/adapters/webhook.js","require":"./dist/adapters/webhook.cjs"},"./markdown":{"types":"./dist/markdown.d.ts","import":"./dist/markdown.js","require":"./dist/markdown.cjs"}},"gitHead":"5918b92ec4265040914085868055e0c1c9b3f3de","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:3c6219ea-8471-4bed-b56d-4ce135c60b95"}},"repository":{"url":"git+https://github.com/apideck-libraries/agent-analytics.git","type":"git"},"_npmVersion":"12.0.2","description":"Track AI agent and bot traffic to your Next.js / Vercel app — PostHog, webhooks, or any custom analytics backend. Detects Claude, ChatGPT, Perplexity, Google-Extended, and more.","directories":{},"_nodeVersion":"22.23.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0","@types/node":"^20.14.0"},"_npmOperationalInternal":{"tmp":"tmp/agent-analytics_0.14.0_1785662801211_0.328957749789339","host":"s3://npm-registry-packages-npm-production"}},"0.15.0":{"name":"@apideck/agent-analytics","version":"0.15.0","keywords":["ai","agents","analytics","bot-detection","claude","chatgpt","perplexity","llm","posthog","nextjs","vercel","middleware"],"author":{"name":"Apideck"},"license":"MIT","_id":"@apideck/agent-analytics@0.15.0","maintainers":[{"name":"gdewilde","email":"gertjan@apideck.com"},{"name":"nicklloyd","email":"nick@apideck.com"},{"name":"ritiksingh7","email":"ritik@apideck.com"},{"name":"samzani","email":"samir.amzani@gmail.com"},{"name":"lagoni","email":"jonas-lt@live.dk"},{"name":"jakeprins","email":"jake@apideck.com"},{"name":"gmenoiaa","email":"gmenoiaa@gmail.com"}],"homepage":"https://github.com/apideck-libraries/agent-analytics#readme","bugs":{"url":"https://github.com/apideck-libraries/agent-analytics/issues"},"dist":{"shasum":"343d3596f107d5b01888caf20036849a19b6b47e","tarball":"https://registry.npmjs.org/@apideck/agent-analytics/-/agent-analytics-0.15.0.tgz","fileCount":35,"integrity":"sha512-jCU1znc7dwO/KClX1bZ0g9hN67TsFZ4z8synIz/WOvfzEWMO7qbMWyBvsYy3bfulqtJ+ju9ve5Xhs5Xh8pGwHA==","signatures":[{"sig":"MEUCIEAb23SPEAfz2BjNzQEWrzr4LujeqjY6Jmd1qhaNmNDwAiEAvebEdtE4nS0+Er73kqQ4vwfKssXUWPSw2l0Rwm/wl04=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@apideck%2fagent-analytics@0.15.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":679791},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./verify":{"types":"./dist/verify.d.ts","import":"./dist/verify.js","require":"./dist/verify.cjs"},"./posthog":{"types":"./dist/adapters/posthog.d.ts","import":"./dist/adapters/posthog.js","require":"./dist/adapters/posthog.cjs"},"./webhook":{"types":"./dist/adapters/webhook.d.ts","import":"./dist/adapters/webhook.js","require":"./dist/adapters/webhook.cjs"},"./markdown":{"types":"./dist/markdown.d.ts","import":"./dist/markdown.js","require":"./dist/markdown.cjs"}},"gitHead":"9b9da3f8cd74f705ff8ed210ea8238ed92faf6bf","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","test:unit":"vitest run --exclude 'test/integration.test.ts'","typecheck":"tsc --noEmit","test:watch":"vitest","prepublishOnly":"npm run build","test:integration":"vitest run test/integration.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:3c6219ea-8471-4bed-b56d-4ce135c60b95"}},"repository":{"url":"git+https://github.com/apideck-libraries/agent-analytics.git","type":"git"},"_npmVersion":"12.0.2","description":"Track AI agent and bot traffic to your Next.js / Vercel app — PostHog, webhooks, or any custom analytics backend. Detects Claude, ChatGPT, Perplexity, Google-Extended, and more.","directories":{},"_nodeVersion":"22.23.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0","@types/node":"^20.14.0"},"_npmOperationalInternal":{"tmp":"tmp/agent-analytics_0.15.0_1785676766642_0.5218475686202206","host":"s3://npm-registry-packages-npm-production"}},"0.16.0":{"name":"@apideck/agent-analytics","version":"0.16.0","keywords":["ai","agents","analytics","bot-detection","claude","chatgpt","perplexity","llm","posthog","nextjs","vercel","middleware"],"author":{"name":"Apideck"},"license":"MIT","_id":"@apideck/agent-analytics@0.16.0","maintainers":[{"name":"gdewilde","email":"gertjan@apideck.com"},{"name":"nicklloyd","email":"nick@apideck.com"},{"name":"ritiksingh7","email":"ritik@apideck.com"},{"name":"samzani","email":"samir.amzani@gmail.com"},{"name":"lagoni","email":"jonas-lt@live.dk"},{"name":"jakeprins","email":"jake@apideck.com"},{"name":"gmenoiaa","email":"gmenoiaa@gmail.com"}],"homepage":"https://github.com/apideck-libraries/agent-analytics#readme","bugs":{"url":"https://github.com/apideck-libraries/agent-analytics/issues"},"dist":{"shasum":"637733c4455f4679872e042078de2868a9d621f0","tarball":"https://registry.npmjs.org/@apideck/agent-analytics/-/agent-analytics-0.16.0.tgz","fileCount":51,"integrity":"sha512-wzabOpy3NDgBaZVYojJJf9LDRe1pQgwc/vt5RWhMDFLlAXOJ4Y5UXAmeueNQpU5CHAOSoALjy/Vy5Z+MUzjW5g==","signatures":[{"sig":"MEYCIQCHa2KwtId9HC3+nuDQn5urCyjSJThs/Bl3gEUsUL1BUwIhAOdmpi5BETTx8mCmEix9cp+gw8luyTXfI0WR2cHQ8QuM","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@apideck%2fagent-analytics@0.16.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":761896},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./verify":{"types":"./dist/verify.d.ts","import":"./dist/verify.js","require":"./dist/verify.cjs"},"./posthog":{"types":"./dist/adapters/posthog.d.ts","import":"./dist/adapters/posthog.js","require":"./dist/adapters/posthog.cjs"},"./webhook":{"types":"./dist/adapters/webhook.d.ts","import":"./dist/adapters/webhook.js","require":"./dist/adapters/webhook.cjs"},"./firewall":{"types":"./dist/firewall.d.ts","import":"./dist/firewall.js","require":"./dist/firewall.cjs"},"./markdown":{"types":"./dist/markdown.d.ts","import":"./dist/markdown.js","require":"./dist/markdown.cjs"},"./payments":{"types":"./dist/pay.d.ts","import":"./dist/pay.js","require":"./dist/pay.cjs"}},"gitHead":"107e30403cc1431f12359a5fcb1f94748d018e26","scripts":{"dev":"tsup --watch","size":"node scripts/check-size.mjs","test":"vitest run","build":"tsup","test:unit":"vitest run --exclude 'test/integration.test.ts'","typecheck":"tsc --noEmit","test:watch":"vitest","prepublishOnly":"npm run build","test:integration":"vitest run test/integration.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:3c6219ea-8471-4bed-b56d-4ce135c60b95"}},"repository":{"url":"git+https://github.com/apideck-libraries/agent-analytics.git","type":"git"},"_npmVersion":"12.0.2","description":"Track AI agent and bot traffic to your Next.js / Vercel app — PostHog, webhooks, or any custom analytics backend. Detects Claude, ChatGPT, Perplexity, Google-Extended, and more.","directories":{},"_nodeVersion":"22.23.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0","@types/node":"^20.14.0"},"_npmOperationalInternal":{"tmp":"tmp/agent-analytics_0.16.0_1785692322265_0.22504305828557758","host":"s3://npm-registry-packages-npm-production"}},"0.17.0":{"name":"@apideck/agent-analytics","version":"0.17.0","keywords":["ai","agents","analytics","bot-detection","claude","chatgpt","perplexity","llm","posthog","nextjs","vercel","middleware"],"author":{"name":"Apideck"},"license":"MIT","_id":"@apideck/agent-analytics@0.17.0","maintainers":[{"name":"gdewilde","email":"gertjan@apideck.com"},{"name":"nicklloyd","email":"nick@apideck.com"},{"name":"ritiksingh7","email":"ritik@apideck.com"},{"name":"samzani","email":"samir.amzani@gmail.com"},{"name":"jakeprins","email":"jake@apideck.com"},{"name":"gmenoiaa","email":"gmenoiaa@gmail.com"}],"homepage":"https://github.com/apideck-libraries/agent-analytics#readme","bugs":{"url":"https://github.com/apideck-libraries/agent-analytics/issues"},"dist":{"shasum":"27b75144c7d1c84d6b4d7e3fc5bbb4de55fbc5f4","tarball":"https://registry.npmjs.org/@apideck/agent-analytics/-/agent-analytics-0.17.0.tgz","fileCount":51,"integrity":"sha512-MVpvM4qW01cwVeaw46zNqVBExmjsQBeHMI3L+HEOKgy3MQ/c3P8BxjjhWSRDOOFpTrXSaidiByVFJr9r/hsPCg==","signatures":[{"sig":"MEYCIQCaiOGsDL0/cZWJMQB4v8iMQCZST8osM3sUchQj7fLNDQIhAJ080W4L41YfqSoxw2ymg/1jMnxumUhrqQQmlptL/uvY","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@apideck%2fagent-analytics@0.17.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":807088},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./verify":{"types":"./dist/verify.d.ts","import":"./dist/verify.js","require":"./dist/verify.cjs"},"./posthog":{"types":"./dist/adapters/posthog.d.ts","import":"./dist/adapters/posthog.js","require":"./dist/adapters/posthog.cjs"},"./webhook":{"types":"./dist/adapters/webhook.d.ts","import":"./dist/adapters/webhook.js","require":"./dist/adapters/webhook.cjs"},"./firewall":{"types":"./dist/firewall.d.ts","import":"./dist/firewall.js","require":"./dist/firewall.cjs"},"./markdown":{"types":"./dist/markdown.d.ts","import":"./dist/markdown.js","require":"./dist/markdown.cjs"},"./payments":{"types":"./dist/pay.d.ts","import":"./dist/pay.js","require":"./dist/pay.cjs"}},"gitHead":"c485ceb2960e5ec78105216a0dee0168fb09a5f5","scripts":{"dev":"tsup --watch","size":"node scripts/check-size.mjs","test":"vitest run","build":"tsup","test:unit":"vitest run --exclude 'test/integration.test.ts'","typecheck":"tsc --noEmit","test:watch":"vitest","prepublishOnly":"npm run build","test:integration":"vitest run test/integration.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:3c6219ea-8471-4bed-b56d-4ce135c60b95"}},"repository":{"url":"git+https://github.com/apideck-libraries/agent-analytics.git","type":"git"},"_npmVersion":"12.0.2","description":"Track AI agent and bot traffic to your Next.js / Vercel app — PostHog, webhooks, or any custom analytics backend. Detects Claude, ChatGPT, Perplexity, Google-Extended, and more.","directories":{},"_nodeVersion":"22.23.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","typescript":"^5.6.0","@types/node":"^20.14.0"},"_npmOperationalInternal":{"tmp":"tmp/agent-analytics_0.17.0_1785826633556_0.30754610341241073","host":"s3://npm-registry-packages-npm-production"}}},"time":{"created":"2026-04-19T07:00:18.818Z","modified":"2026-09-17T09:13:33.100Z","0.1.0":"2026-04-19T07:00:19.048Z","0.1.1":"2026-04-19T08:04:04.096Z","0.2.0":"2026-04-19T08:31:19.767Z","0.3.0":"2026-04-19T08:44:13.986Z","0.4.0":"2026-04-20T22:49:06.049Z","0.5.0":"2026-04-20T23:53:30.337Z","0.6.0":"2026-04-21T04:29:56.892Z","0.7.0":"2026-04-26T20:22:01.698Z","0.8.0":"2026-04-26T20:22:30.105Z","0.9.0":"2026-04-26T20:54:28.256Z","0.10.0":"2026-08-02T03:53:45.245Z","0.11.0":"2026-08-02T04:18:09.285Z","0.12.0":"2026-08-02T08:42:19.340Z","0.13.0":"2026-08-02T08:46:04.323Z","0.14.0":"2026-08-02T09:26:41.384Z","0.15.0":"2026-08-02T13:19:26.793Z","0.16.0":"2026-08-02T17:38:42.484Z","0.17.0":"2026-08-04T06:57:13.725Z"},"bugs":{"url":"https://github.com/apideck-libraries/agent-analytics/issues"},"author":{"name":"Apideck"},"license":"MIT","homepage":"https://github.com/apideck-libraries/agent-analytics#readme","keywords":["ai","agents","analytics","bot-detection","claude","chatgpt","perplexity","llm","posthog","nextjs","vercel","middleware"],"repository":{"url":"git+https://github.com/apideck-libraries/agent-analytics.git","type":"git"},"description":"Track AI agent and bot traffic to your Next.js / Vercel app — PostHog, webhooks, or any custom analytics backend. Detects Claude, ChatGPT, Perplexity, Google-Extended, and more.","maintainers":[{"email":"gertjan@apideck.com","name":"gdewilde"},{"email":"nick@apideck.com","name":"nicklloyd"},{"email":"ritik@apideck.com","name":"ritiksingh7"},{"email":"samir.amzani@gmail.com","name":"samzani"},{"email":"mithgroth@gmail.com","name":"mithgroth"},{"email":"gmenoiaa@gmail.com","name":"gmenoiaa"}],"readme":"<div align=\"center\">\n\n# agent-analytics\n\n### See the agents your JavaScript can't.\n\n**Drop-in Next.js / Vercel middleware that tracks ClaudeBot, GPTBot, Perplexity, and 20+ AI crawlers in PostHog — or any analytics backend you already pay for.**\n\n[![npm version](https://img.shields.io/npm/v/@apideck/agent-analytics.svg?style=flat-square&color=2563eb)](https://www.npmjs.com/package/@apideck/agent-analytics)\n[![npm downloads](https://img.shields.io/npm/dm/@apideck/agent-analytics.svg?style=flat-square&color=2563eb)](https://www.npmjs.com/package/@apideck/agent-analytics)\n[![bundle size](https://img.shields.io/bundlephobia/minzip/@apideck/agent-analytics?style=flat-square&color=2563eb&label=gzipped)](https://bundlephobia.com/package/@apideck/agent-analytics)\n[![CI](https://img.shields.io/github/actions/workflow/status/apideck-libraries/agent-analytics/ci.yml?style=flat-square&label=ci)](https://github.com/apideck-libraries/agent-analytics/actions)\n[![license](https://img.shields.io/npm/l/@apideck/agent-analytics?style=flat-square&color=2563eb)](./LICENSE)\n[![typescript](https://img.shields.io/badge/TypeScript-strict-3178c6?style=flat-square)](./tsconfig.json)\n\n[**Install**](#install) · [**Quick start**](#quick-start-60-seconds-to-your-first-event) · [**How it works**](#how-it-works) · [**Adapters**](#built-in-adapters) · [**Markdown mirror**](#advanced-markdown-mirror-for-docs-sites) · [**FAQ**](#faq)\n\n</div>\n\n---\n\n## The problem\n\nClient-side analytics libraries run in the browser. AI crawlers don't. That means **every time ClaudeBot, GPTBot, or Perplexity fetches a page on your site, your dashboard stays empty.**\n\nYou can't see:\n\n- Which AI agents are reading your docs, marketing pages, or blog\n- Which pages they actually fetch (vs. which you *think* they should)\n- Which agent-driven referrals convert\n- How much of your \"traffic\" is actually LLM training pipelines\n\nServer logs have the data, but turning them into analytics is a pipeline project. This library is the one-line version.\n\n## What you get\n\n```ts\nimport { trackVisit, posthogAnalytics } from '@apideck/agent-analytics'\n\nconst analytics = posthogAnalytics({ apiKey: process.env.POSTHOG_KEY! })\n\nexport function middleware(req: NextRequest) {\n  void trackVisit(req, { analytics })   // ← that's the whole thing\n  return NextResponse.next()\n}\n```\n\nOne line of middleware. Fire-and-forget. Zero impact on your response latency. Events in PostHog within seconds.\n\n<details>\n<summary><b>What shows up in your analytics</b> (click to expand)</summary>\n\n```jsonc\n{\n  \"event\": \"doc_view\",\n  \"distinct_id\": \"anon_7f3a1b2c\",          // hashed ip:ua, no person profile\n  \"timestamp\": \"2026-04-19T08:30:00.000Z\",\n  \"properties\": {\n    \"$process_person_profile\": false,       // PostHog: don't create a person\n    \"$current_url\": \"https://example.com/docs/intro\",\n    \"path\": \"/docs/intro\",\n    \"method\": \"GET\",\n    \"user_agent\": \"ClaudeBot/1.0 (+https://claude.ai/bot)\",\n    \"is_ai_bot\": true,                      // strict: matches a branded AI crawler\n    \"bot_name\": \"Claude\",                   // 'Claude' | 'ChatGPT' | ... | 'curl' | 'axios' | 'Electron' | 'Browser' | 'Other'\n    \"ua_category\": \"declared-crawler\",      // 'declared-crawler' | 'coding-agent-hint' | 'browser' | 'other'\n    \"coding_agent_hint\": false,             // loose: HTTP-library / automation UA (curl, axios, got, colly, Electron, ...)\n    \"referer\": \"https://claude.ai/\",\n    \"source\": \"page-view\"                   // whatever label you passed\n  }\n}\n```\n\nNow you can build:\n- **AI-vs-human traffic ratio** over time\n- **Breakdown by agent** (Claude vs ChatGPT vs Perplexity vs Google-Extended)\n- **Top pages for agents** (what do they actually read?)\n- **Conversion funnels** from agent referral → human visit → sign-up\n- **Anomaly detection** when a new bot starts hammering your site\n\n</details>\n\n---\n\n## Charging for training crawls (experimental)\n\n> **⚠️ Experimental.** The payment surface — `paymentRequired`, `paymentGate`,\n> `x402Gateway`, `mppxGateway` — may change without a major version bump. The\n> protocols are weeks old and still moving: x402 and MPP are both live but their\n> specs are unstable, MPP had not publicly pinned a settlement-confirmation\n> header at the time of writing, and no agent in our own production traffic has\n> yet presented a payment credential. Detection, verification and policy are\n> stable; this is not. Do not put it on a revenue-critical path yet.\n\n### Meter first. Charge later, if at all.\n\nPer-request 402 is what x402 and MPP define, and it is the wrong shape for a\ntraining sweep. On one production site that is ~199,000 training requests a\nmonth: three times the traffic once you add pay-and-retry, 199,000 settlements\nwhose per-transaction cost exceeds any sane per-page price, and — decisively —\n**no crawler in the wild retries a 402**. Charging per request is blocking with\nextra steps.\n\nSo start by counting:\n\n```ts\nimport { paymentGate } from '@apideck/agent-analytics/payments'\nimport { combinedVerifier } from '@apideck/agent-analytics/verify'\n\nconst gate = await paymentGate(req, {\n  verify: combinedVerifier(),\n  meter: { record: (e) => warehouse.insert(e) } // training only\n})\nif (gate.response) return gate.response\nreturn gate.decorate(await serve(req))\n```\n\n`meter` fires only for training traffic. Retrieval and search are served free\nand never counted, because charging the channel that sends you readers is the\none outcome this design exists to prevent.\n\n### Then sell a licence, not a page\n\nWhen you know the number, switch to an entitlement: one 402 advertising a bulk\noffer, one settlement, a reusable credential.\n\n```ts\nimport { entitlementGateway } from '@apideck/agent-analytics/payments'\n\nconst gate = await paymentGate(req, {\n  onTraining: 'charge',\n  gateway: entitlementGateway({\n    store: myKV,                    // lookup + consume; quota state is yours\n    offer: { units: 1_000_000, unit: 'pages', validForSeconds: 2_592_000, price: '$400' },\n    challenges: [{ protocol: 'mpp', id, realm: 'example.com', method: 'tempo' }]\n  })\n})\n```\n\n```\n402  once, advertising the licence\n200  every request after, quota −1\n402  again when it runs out\n```\n\nUnknown, expired and exhausted credentials all return the same challenge —\ndistinguishing them would turn the endpoint into an oracle for probing quota.\n\nMPP's reusable `Authorization: Payment` credential suits this better than\nx402's per-resource signature, which proves payment for a single URL.\n\nMeasured against real traffic shapes:\n\n```\n402    training   charge  GPTBot\nserve  retrieval  allow   ChatGPT-User\n403    training   block   ClaudeBot from an unpublished IP\n402    training   charge  ClaudeBot from a real Anthropic IP\nserve  search     allow   Googlebot, PerplexityBot\nserve  preview    allow   Slackbot, facebookexternalhit\n```\n\n`preview` is its own intent rather than a flavour of `retrieval`: a link unfurl\nis a person pasting your URL into a conversation, not an assistant answering a\nquestion. Folding the two together would inflate the retrieval number, which is\nthe one figure the split exists to measure.\n\nSettlement is never ours. `mppxGateway` wraps Stripe's MPP SDK; `x402Gateway`\ncalls a facilitator you supply. The library emits challenges and reads\ncredentials — holding money would drag PCI scope into edge middleware.\n\n## Cryptographic verification (Web Bot Auth)\n\nPublished IP ranges were always the weak form of identity. [Web Bot\nAuth](https://blog.cloudflare.com/web-bot-auth/) is the strong one: an RFC 9421\nHTTP Message Signatures profile where an agent signs each request with Ed25519\nand publishes its keys at a well-known directory. Backed by Cloudflare, Amazon,\nAkamai and OpenAI, with an IETF working group chartered in 2026.\n\n```ts\nimport { combinedVerifier } from '@apideck/agent-analytics/verify'\n\nvoid trackVisit(req, { analytics, verify: combinedVerifier() })\n```\n\n`combinedVerifier` prefers the signature and falls back to ranges:\n\n| | published IP ranges | Web Bot Auth |\n| --- | --- | --- |\n| Coverage | 4 vendors | any agent that signs |\n| Freshness | rots; needs weekly refresh | none needed |\n| False `spoofed` | stale list accuses real crawlers | impossible |\n| Agents on a user's machine | unverifiable | signable |\n\nA present-but-invalid signature is decisive: it returns `spoofed` even if the\nclient IP happens to sit in a published range, so a forged signature cannot be\nlaundered by the weaker check. Unsigned traffic is `unverifiable`, never\n`spoofed` — most agents do not sign yet, and treating silence as forgery would\nmislabel nearly all real traffic.\n\nUnsigned requests cost nothing: the check returns before any I/O. Signed ones\nfetch the signer's key directory once per origin and cache it for an hour.\n\n## Upgrading to 0.12\n\nFour breaking changes, all deliberate. Each one existed because the previous\nbehaviour was wrong in a way that failed quietly.\n\n**`distinctId` is now keyed.** The old identifier was an unsalted 32-bit djb2\nover `ip:userAgent`. Since the user agent ships in plaintext on the same event,\nonly the IP had to be searched — a laptop recovered a residential address in\n75 seconds. Set `idSecret` (or `AGENT_ANALYTICS_ID_SECRET`) to a stable secret;\nwithout one, a random per-instance secret is used, which stays private but\nmeans ids no longer correlate across instances. Existing ids will not match the\nnew ones either way.\n\n```diff\n- void trackVisit(req, { analytics })\n+ void trackVisit(req, { analytics, idSecret: process.env.AGENT_ANALYTICS_ID_SECRET })\n```\n\n**`verifyIdentity: true` is replaced by an injected verifier.** The published\nIP range tables are the largest thing in the package, and importing them from\nthe root entry shipped them to every consumer whether or not they verified\nanything. They now live behind `@apideck/agent-analytics/verify`.\n\n```diff\n- void trackVisit(req, { analytics, verifyIdentity: true })\n+ import { verifyRequest } from '@apideck/agent-analytics/verify'\n+ void trackVisit(req, { analytics, verify: verifyRequest })\n```\n\n**Caller `properties` no longer override computed fields.** They were spread\nlast, so `properties: { path }` silently replaced the real path and\n`properties: { is_ai_bot }` could contradict the classification on the same\nevent. Non-colliding keys are unaffected.\n\n**Headless automation is labelled `Headless`, not `Browser`.** A browser user\nagent with headless headers accounted for 79% of one production site's agent\ntraffic, and calling it `Browser` hid it behind the obvious\n`bot_name != 'Browser'` filter. `headless_score` and `headless_likely` are now\nomitted on declared crawlers and HTTP clients, where they fired on 99% of\nevents and carried no signal.\n\n**Node 18 is no longer supported; the minimum is Node 20.** `globalThis.crypto`\nonly became available by default in Node 19, and shipping a `node:crypto`\nfallback would mean a static import of a Node builtin in a library whose main\ntarget is edge runtimes. Node 18 reached end of life in April 2025. Runtimes\nwithout Web Crypto now fail with an explicit message rather than a confusing\n`undefined` dereference.\n\n### Also in 0.12\n\n- Adapters surface non-2xx responses as `CaptureTransportError` instead of\n  swallowing them. Pass `onError` to `trackVisit` to see them; capture still\n  never throws into the response path.\n- Outbound captures carry a 3s `AbortSignal` (`timeoutMs` to change it).\n- Root bundle is 65% smaller (27.7 kB → 9.6 kB, 3.8 kB gzipped).\n\n## Recommending firewall rules\n\nTurn observed traffic into staged Vercel WAF proposals. It emits *proposals* —\nevery rule comes out in `log` mode and Vercel stages rule changes as drafts, so\nnothing is live until you run `vercel firewall publish` yourself.\n\n```ts\nimport { recommendFirewallRules, firewallScript } from '@apideck/agent-analytics/firewall'\n\nconst rules = recommendFirewallRules(observations) // aggregate from your warehouse\nconsole.log(firewallScript(rules))                // runnable, commented bash\n```\n\nTwo rules it will not break, both from measurement rather than taste:\n\n- **Retrieval and search agents are never proposed for blocking**, and a `bypass`\n  rule protecting them is emitted *first* so later rules cannot catch them.\n  Rules evaluate top to bottom, and 60% of AI traffic on one production site is\n  a person asking a question.\n- **Training crawlers get rate limits, not denials.** Denying them removes you\n  from future training sets, which is a discoverability decision rather than a\n  default.\n\nOnly a failed verification earns a proposed `deny`. Every recommendation carries\nits `evidence`, a `risk` rating, and a `caveat` where over-blocking is plausible\n— the datacenter-ASN rule is marked `high` risk because corporate VPNs and\nprivacy relays egress from hosting networks.\n\n### Pools that no per-address threshold catches\n\nA rotating proxy pool is built so that no single address looks abusive. Measured\non one production site: 34 addresses across 11 countries, one user agent each,\nthe heaviest doing 100 requests in a day — every one invisible to a per-address\nthreshold, while collectively sweeping the site.\n\nVolume cannot separate that from real readers, so the burst rule keys on *rate*,\nwhich needs `spanSeconds` on your observations:\n\n```ts\n{ ip: '104.28.233.73', requests: 31, distinctPaths: 16, spanSeconds: 1 }\n// → 1,860 requests/min. Not a person.\n```\n\nThe rule is only safe because its condition excludes static assets. The WAF sees\nevery request; the middleware that produced your observations probably does not,\nso a naive limit on `Mozilla` throttles a real visitor on their first page view.\nOverride `assetExclusions` if your app does not serve assets from `/_next/`.\n\nSee [`docs/TESTING-PAYMENTS.md`](./docs/TESTING-PAYMENTS.md) for testing the\npayment path end to end.\n\n## Entry points\n\nThe root carries detection, classification, policy and capture — what every\nconsumer needs. Everything optional lives behind a subpath, so it only reaches\nyour bundle if you import it.\n\n| Import | Contains | Root bundle cost |\n| --- | --- | ---: |\n| `@apideck/agent-analytics` | detection, classification, `agentPolicy`, `trackVisit` | 11.6 kB / **4.5 kB gz** |\n| `…/verify` | Web Bot Auth + published IP range tables | 19.0 kB |\n| `…/payments` | 402 challenges, gateways, entitlements | 10.9 kB |\n| `…/firewall` | WAF rule recommendations (offline tool) | 6.8 kB |\n| `…/markdown` | Markdown-twin content negotiation | 2.0 kB |\n\nThis split is load-bearing rather than tidy-minded. Exporting the payment and\nfirewall surfaces from the root once pushed it from 9.6 kB to 22.5 kB — every\nsite paid for a firewall recommender that will never run in middleware. Nothing\nfailed; the number just drifted for weeks until someone looked.\n\nSo CI now enforces it. `npm run size` checks each entry against\n[`size-budget.json`](./size-budget.json) and fails the build on a regression:\n\n```\nentry               gzipped     budget  used\ndist/index.js       4.44 kB    4.88 kB   91%\ndist/verify.js      6.25 kB    7.42 kB   84%\ndist/pay.js         4.05 kB    4.49 kB   90%\n```\n\nRaising a budget is deliberate — `npm run size -- --update`, and say why in the\ncommit.\n\n## Install\n\n```bash\nnpm install @apideck/agent-analytics\n# or\npnpm add @apideck/agent-analytics\n# or\nyarn add @apideck/agent-analytics\n```\n\nZero dependencies. Runs on Node 18+, Edge, Bun, and anywhere the Web Fetch API exists.\n\n## Quick start (60 seconds to your first event)\n\n<table>\n<tr>\n<td width=\"33%\" valign=\"top\">\n\n### 1. Pick an adapter\n\n```ts\nimport {\n  posthogAnalytics\n} from '@apideck/agent-analytics'\n\nconst analytics = posthogAnalytics({\n  apiKey: process.env.POSTHOG_KEY!\n})\n```\n\nShips with **PostHog**, **webhook**, and **custom** adapters. BYO analytics.\n\n</td>\n<td width=\"33%\" valign=\"top\">\n\n### 2. Wire the middleware\n\n```ts\n// middleware.ts\nimport {\n  trackVisit\n} from '@apideck/agent-analytics'\n\nexport function middleware(req) {\n  void trackVisit(req, {\n    analytics,\n    source: 'page-view'\n  })\n  return NextResponse.next()\n}\n```\n\nWorks in any middleware that hands you a `Request`.\n\n</td>\n<td width=\"33%\" valign=\"top\">\n\n### 3. Ship it\n\n```bash\nvercel --prod\n```\n\nHit any page with a spoofed UA:\n\n```bash\ncurl -A \"ClaudeBot/1.0\" \\\n  https://yoursite.com/\n```\n\nEvent lands in PostHog in seconds.\n\n</td>\n</tr>\n</table>\n\n---\n\n## How it works\n\n```text\n                   Request                   Response (unchanged)\n   Agent ─────────────────────►  middleware ───────────────────► Agent\n                                      │\n                                      │ fire-and-forget\n                                      │ keepalive: true\n                                      ▼\n                            ┌──────────────────┐\n                            │  AnalyticsAdapter │\n                            │  (PostHog /       │\n                            │   webhook /       │\n                            │   custom fn)      │\n                            └──────────────────┘\n```\n\nThe middleware call:\n\n1. **Reads UA** from `req.headers.get('user-agent')`\n2. **Matches against** `AI_BOT_PATTERN` (ClaudeBot, GPTBot, PerplexityBot, Google-Extended, Applebot-Extended, CCBot, Bytespider, Amazonbot, Meta-ExternalAgent, MistralAI-User, Cursor, Windsurf, and more)\n3. **Hashes `ip:ua`** with djb2 → stable anon distinct_id (same bot from same network = same visitor, no PII)\n4. **Posts to your adapter** with `keepalive: true` so the request survives after the response returns\n5. **Swallows errors** — a downed analytics backend never breaks your response\n\nBy default every request is captured so coding-agent traffic (axios, curl, Electron, …) surfaces alongside branded crawlers. Pass `onlyBots: true` to restrict capture to UAs matching the built-in AI bot pattern.\n\n---\n\n## Who's detected out of the box\n\n<table>\n<tr><th>Agent</th><th>UA signature</th><th>bot_name label</th></tr>\n<tr><td><b>Anthropic</b></td><td><code>ClaudeBot</code>, <code>Claude-User</code>, <code>Anthropic-*</code></td><td><code>Claude</code></td></tr>\n<tr><td><b>OpenAI</b></td><td><code>ChatGPT-User</code>, <code>GPTBot</code>, <code>OAI-SearchBot</code></td><td><code>ChatGPT</code></td></tr>\n<tr><td><b>Perplexity</b></td><td><code>PerplexityBot</code>, <code>Perplexity-User</code></td><td><code>Perplexity</code></td></tr>\n<tr><td><b>Google</b></td><td><code>Google-Extended</code>, <code>Googlebot</code></td><td><code>Google</code></td></tr>\n<tr><td><b>Apple</b></td><td><code>Applebot-Extended</code>, <code>Applebot</code></td><td><code>Apple</code></td></tr>\n<tr><td><b>Meta</b></td><td><code>Meta-ExternalAgent</code>, <code>FacebookBot</code></td><td><code>Meta</code></td></tr>\n<tr><td><b>Amazon</b></td><td><code>Amazonbot</code></td><td><code>Amazon</code></td></tr>\n<tr><td><b>Bytedance</b></td><td><code>Bytespider</code></td><td><code>Bytespider</code></td></tr>\n<tr><td><b>Common Crawl</b></td><td><code>CCBot</code></td><td><code>Common Crawl</code></td></tr>\n<tr><td><b>Mistral</b></td><td><code>MistralAI-User</code></td><td><code>Mistral</code></td></tr>\n<tr><td><b>Cohere</b></td><td><code>cohere-ai</code></td><td><code>Cohere</code></td></tr>\n<tr><td><b>DuckDuckGo</b></td><td><code>DuckAssistBot</code></td><td><code>DuckDuckGo</code></td></tr>\n<tr><td><b>You.com</b></td><td><code>YouBot</code></td><td><code>You.com</code></td></tr>\n<tr><td><b>AI2</b></td><td><code>AI2Bot</code></td><td><code>AI2</code></td></tr>\n<tr><td><b>Diffbot</b></td><td><code>Diffbot</code></td><td><code>Diffbot</code></td></tr>\n<tr><td><b>Coding agents</b></td><td><code>Cursor</code>, <code>Windsurf</code></td><td><code>Cursor</code> / <code>Windsurf</code></td></tr>\n</table>\n\nNew agents appear every month. Patch releases ship as the list grows — watch the repo for updates. Raise a PR if you spot one we're missing.\n\n### Coding agents (loose detection — `coding_agent_hint: true`)\n\nCoding agents like Claude Code, Cline, Cursor, and Windsurf **don't identify themselves by name** in their user agent. They use whatever HTTP library they're built on, so detection is a loose heuristic — the UAs below are *also* used by legitimate curl scripts, CI jobs, and server-to-server traffic.\n\n`is_ai_bot` stays `false` for these so your strict AI-traffic segment is clean. The `coding_agent_hint` property is the wider net; pair it with other signals (path patterns, [JA4 fingerprints via Vercel Log Drains](https://vercel.com/docs/observability/log-drains), HEAD-then-GET request shape) when you need higher confidence.\n\n| Agent | Signature observed | `bot_name` |\n|---|---|---|\n| Claude Code | `axios/1.8.4` | `axios` |\n| Cline / Junie | `curl/8.4.0` | `curl` |\n| Cursor | `got (sindresorhus/got)` | `got` |\n| Windsurf | `colly` (Go) | `colly` |\n| VS Code | `Electron/` marker | `Electron` |\n| Other automation | `node-fetch`, `python-requests`, `Go-http-client`, `okhttp`, `aiohttp`, `Deno` | exact library name |\n\nPlaywright-based agents (Aider, OpenCode) spoof full Mozilla/Safari UAs and are **indistinguishable from real browsers by UA alone**. They'll show up as `bot_name: Browser`, `ua_category: browser`. Catching those needs TLS fingerprinting (JA4) or behavioural analysis.\n\nCredit: coding-agent signatures catalogued by [Addy Osmani](https://addyosmani.com/blog/agentic-engine-optimization/).\n\n---\n\n## Built-in adapters\n\n### `posthogAnalytics`\n\n```ts\nimport { posthogAnalytics } from '@apideck/agent-analytics'\n\nconst analytics = posthogAnalytics({\n  apiKey: process.env.NEXT_PUBLIC_POSTHOG_KEY!,\n  host: 'https://eu.i.posthog.com'        // optional; defaults to US cloud\n})\n```\n\nHost can be the PostHog cloud (`us.i.posthog.com`, `eu.i.posthog.com`) **or** your own reverse-proxy domain (e.g. `https://svc.yourdomain.com`) to dodge ad-blockers. Scheme is optional — both `'https://host'` and `'host'` work.\n\n### `webhookAnalytics`\n\n```ts\nimport { webhookAnalytics } from '@apideck/agent-analytics'\n\nconst analytics = webhookAnalytics({\n  url: 'https://collector.example.com/events',\n  headers: { Authorization: `Bearer ${process.env.TOKEN}` },\n  transform: (event) => ({              // optional: reshape for your backend\n    type: event.event,\n    user: event.distinctId,\n    ...event.properties\n  })\n})\n```\n\n### `customAnalytics`\n\n```ts\nimport { customAnalytics } from '@apideck/agent-analytics'\nimport { Mixpanel } from 'mixpanel'\n\nconst mp = Mixpanel.init(process.env.MIXPANEL_TOKEN!)\n\nconst analytics = customAnalytics((event) => {\n  mp.track(event.event, { distinct_id: event.distinctId, ...event.properties })\n})\n```\n\nAny `{ capture(event): Promise<void> | void }` object is a valid adapter. Compose multiple by fanning out in a custom callback.\n\n---\n\n## Advanced: Markdown mirror for docs sites\n\nContent-heavy sites should serve **clean Markdown** when an agent asks for it — that's what makes your docs actually useful to coding agents, not just indexable. The `/markdown` subpath exports the helpers that power [developers.apideck.com](https://developers.apideck.com)'s agent-readiness stack:\n\n```ts\nimport {\n  markdownServeDecision,   // decide if this request should get Markdown\n  markdownHeaders,         // Content-Type, Content-Signal, x-markdown-tokens\n  synthesizeMarkdownPointer // fallback for URLs without a mirror\n} from '@apideck/agent-analytics/markdown'\n```\n\nThree triggers, one decision helper:\n\n| Trigger | Example | `reason` |\n|---|---|---|\n| AI-bot UA on any URL | `curl -A ClaudeBot /docs/intro` | `ua-rewrite` |\n| `.md` suffix | `curl /docs/intro.md` | `md-suffix` |\n| `Accept: text/markdown` header | `curl -H \"Accept: text/markdown\" /docs/intro` | `accept-header` |\n\nFull middleware example: [`README.md → Markdown mirror helpers`](./README.md#markdown-mirror-helpers) section, or copy from [the reference implementation](https://github.com/apideck-io/developer-docs/blob/main/src/middleware.ts).\n\n---\n\n## Advanced: verifying crawler identity against published IP ranges\n\nUser agents are trivially forged — `curl -A \"ChatGPT-User\"` is indistinguishable\nfrom the real thing at the UA layer. Set `verifyIdentity: true` to check the\nclient IP against the vendor's published crawler ranges:\n\n```ts\nvoid trackVisit(request, {\n  analytics,\n  verifyIdentity: true,\n  captureIp: true // not required, but useful for auditing a 'spoofed' verdict\n})\n```\n\nThree properties land on the event:\n\n| property | values |\n| --- | --- |\n| `bot_verification` | `verified` \\| `spoofed` \\| `unverifiable` \\| `not-claimed` |\n| `bot_verified` | `true` \\| `false` \\| `null` — tri-state, for quick filtering |\n| `bot_verification_reason` | why, when the verdict is `unverifiable` |\n\n### What can actually be verified\n\nOnly vendors that publish a machine-readable range feed: **OpenAI**,\n**Anthropic**, **Perplexity**, and **Apple**. Bytespider, Amazonbot, Meta and\nthe rest report `unverifiable` — never `spoofed`. Collapsing \"we can't check\"\ninto \"impostor\" would be a false accusation, which is why `bot_verified` is\ntri-state rather than a boolean.\n\n### Server-side crawlers vs client-side agents\n\nA published range list covers a vendor's **crawler fleet**, not its products\nthat fetch from the end user's device. Claude Code runs on a developer's\nlaptop, so the request carries *their* IP and will never appear in Anthropic's\nranges. Measured over 30 days of production traffic:\n\n| user agent | events | distinct IPs | in published range |\n| --- | ---: | ---: | ---: |\n| `ClaudeBot` | 13,671 | 236 | 96% |\n| `PerplexityBot` | 6,897 | 158 | 91% |\n| `ChatGPT-User` | ~72,000 | 43 | 99% |\n| `Claude-User` (claude-code CLI) | 6,492 | 4,486 | **0%** |\n| `Perplexity-User` | 493 | 148 | **0%** |\n\nA naive vendor-level check would brand the bottom two rows — roughly 7,000\nlegitimate fetches a month — as impersonation. So the library gates verdicts on\nthe *product*, returning `unverifiable` with reason `client-side-agent` for\nthose. Note the distinction is not a `-User` suffix: OpenAI's `ChatGPT-User`\nfetches server-side from Azure and verifies at ~99%.\n\n### Keeping the ranges fresh\n\nThe bundled snapshot is in `src/bot-ranges.ts`, stamped with\n`BOT_RANGES_CAPTURED_AT`. Refresh it on a schedule:\n\n```bash\nnode scripts/refresh-bot-ranges.mjs\n```\n\nFreshness is the whole game. Nearly every OpenAI prefix is an Azure block and\nAnthropic's are GCP, so \"came from a datacenter\" proves nothing on its own —\nonly membership in the *current* published list does. A stale snapshot produces\nfalse `spoofed` verdicts on real crawlers, so the refresh script refuses to\nwrite a list that shrinks by more than half or when any feed errors.\n\n### Trusting the client IP\n\nThe verdict is only as good as the IP. On Vercel and Cloudflare the edge\noverwrites `x-forwarded-for`, so the first hop is trustworthy. Behind a proxy\nthat passes a client-supplied header through, an attacker controls the value\nand `verified` means nothing — confirm your proxy's behaviour before acting on\nthis data.\n\n---\n\n## Advanced: Peec.ai crawl-insights export\n\n[Peec.ai](https://peec.ai)'s **Agent analytics** product ingests a CSV/CLF access log and produces dashboards on top of it. The Peec docs assume you have a Vercel Log Drain → Axiom (or similar) pipeline that emits these eight columns: `timestamp, request_method, request_url, response_status, client_ip, user_agent, country_code, referer`.\n\nIf you're already running this library, **you can skip the log drain** — your PostHog `agent_visit` events are a near-superset of that schema. Opt into the two privacy-sensitive fields:\n\n```ts\nvoid trackVisit(req, {\n  analytics,\n  captureCountry: true,   // emits country_code from x-vercel-ip-country / cf-ipcountry / x-country-code\n  captureGeo: true,       // emits region, city, latitude, longitude, timezone from x-vercel-ip-* (URL-decoded)\n  captureIp: true         // emits raw client_ip (first hop of x-forwarded-for)\n})\n```\n\nAll three default to **off** so the library stays PII-free out of the box. Enable them only on the deployments you intend to export. `captureGeo` is more identifying than `captureCountry` (city resolution vs. country) — opt in deliberately.\n\nThen export from PostHog with a SQL insight:\n\n```sql\nSELECT\n  timestamp                                       AS timestamp,\n  coalesce(properties.method, 'GET')              AS request_method,\n  properties.$current_url                         AS request_url,\n  '200'                                           AS response_status,   -- middleware runs pre-response\n  coalesce(properties.client_ip, properties.$ip)  AS client_ip,\n  properties.user_agent                           AS user_agent,\n  coalesce(properties.country_code,\n           properties.$geoip_country_code)        AS country_code,\n  properties.referer                              AS referer\nFROM events\nWHERE event = 'agent_visit'\n  AND properties.is_ai_bot = true\n  AND timestamp >= now() - INTERVAL 30 DAY\nORDER BY timestamp DESC\n```\n\n`coalesce` makes the query work on historical events that predate the new fields and on events where `captureCountry` / `captureIp` are off (PostHog's built-in `$ip` and `$geoip_country_code` enrichment fills the gap). Click **Export → CSV** and upload to Peec.\n\n**Caveats:**\n- `response_status` is hardcoded `200` — middleware runs before the response. If Peec filters on status, use the Vercel Log Drain path instead.\n- Drop `is_ai_bot = true` from the `WHERE` clause to also include coding-agent / scraper traffic (curl, axios, headless browsers).\n\n---\n\n## Compared to…\n\n<table>\n<tr>\n<th></th>\n<th align=\"center\">@apideck/agent-analytics</th>\n<th align=\"center\">DIY middleware</th>\n<th align=\"center\">Dark Visitors SaaS</th>\n<th align=\"center\">Cloudflare AI Labyrinth</th>\n</tr>\n<tr>\n<td><b>Tracks agents in your analytics</b></td>\n<td align=\"center\">✓</td>\n<td align=\"center\">✓ (after N hours of glue code)</td>\n<td align=\"center\">✓ (external dashboard)</td>\n<td align=\"center\">✗ (it blocks them instead)</td>\n</tr>\n<tr>\n<td><b>Reuses your analytics backend</b></td>\n<td align=\"center\">✓ PostHog / webhook / any</td>\n<td align=\"center\">✓</td>\n<td align=\"center\">✗ (their dashboard)</td>\n<td align=\"center\">✗</td>\n</tr>\n<tr>\n<td><b>Zero runtime dependencies</b></td>\n<td align=\"center\">✓</td>\n<td align=\"center\">✓</td>\n<td align=\"center\">✗ (SaaS)</td>\n<td align=\"center\">✗ (Cloudflare)</td>\n</tr>\n<tr>\n<td><b>Ships maintained UA list</b></td>\n<td align=\"center\">✓</td>\n<td align=\"center\">✗</td>\n<td align=\"center\">✓</td>\n<td align=\"center\">✓</td>\n</tr>\n<tr>\n<td><b>Markdown-mirror helpers</b></td>\n<td align=\"center\">✓</td>\n<td align=\"center\">✗</td>\n<td align=\"center\">✗</td>\n<td align=\"center\">✗</td>\n</tr>\n<tr>\n<td><b>Monthly cost</b></td>\n<td align=\"center\">$0</td>\n<td align=\"center\">$0 + engineering time</td>\n<td align=\"center\">$$$</td>\n<td align=\"center\">Requires CF plan</td>\n</tr>\n</table>\n\n---\n\n## FAQ\n\n<details>\n<summary><b>Will this slow down my middleware?</b></summary>\n\nNo. `trackVisit` returns a promise you don't await, and the underlying `fetch` uses `keepalive: true` — the browser / runtime guarantees the request completes after your response returns. Your critical path is: `req.headers.get('user-agent')` + a regex test + a `void fetch(...)`. Sub-millisecond.\n\n</details>\n\n<details>\n<summary><b>What if my analytics backend is down?</b></summary>\n\nThe adapter call is wrapped in try/catch — `trackVisit` never throws, even if PostHog / your webhook / your custom callback crashes. You lose the event, not the response.\n\n</details>\n\n<details>\n<summary><b>Does this create PostHog person profiles for every bot?</b></summary>\n\nNo. The event includes `$process_person_profile: false`, which tells PostHog to skip profile creation. Distinct IDs are djb2 hashes of `ip:ua`, so same-bot-same-network collapses into one anonymous visitor for journey analysis, but no \"person\" row gets created.\n\n</details>\n\n<details>\n<summary><b>How do I detect a bot I added to the UA list in my own code?</b></summary>\n\n```ts\nimport { isAiBot, parseBotName } from '@apideck/agent-analytics'\n\nif (isAiBot(req.headers.get('user-agent'))) {\n  // serve Markdown, skip personalisation, add rate limits, etc.\n}\nparseBotName('ClaudeBot/1.0')  // → 'Claude'\n```\n\n</details>\n\n<details>\n<summary><b>Can I use this outside Next.js?</b></summary>\n\nYes. The primary API takes a standard Web Fetch `Request` object. Works in Hono, Bun, Cloudflare Workers, Deno Deploy, Node 18+ HTTP handlers — anywhere you can get a `Request`.\n\n</details>\n\n<details>\n<summary><b>Why not just enable PostHog's bot filtering?</b></summary>\n\nPostHog's bot filter excludes bots from your metrics. This library does the opposite: it makes bots *visible* so you can analyse them deliberately. Complementary — segment by `is_ai_bot` to split the populations.\n\n</details>\n\n<details>\n<summary><b>Is the UA list going to go stale?</b></summary>\n\nAI crawlers keep appearing. We publish patch releases whenever the list changes — `npm update @apideck/agent-analytics` picks them up. If you spot a missing agent, send a PR with a link to the bot's official docs; merges ship the same day.\n\n</details>\n\n---\n\n## Who uses this\n\n- **[developers.apideck.com](https://developers.apideck.com)** — extracted from and battle-tested on the Apideck developer documentation site\n- *Your company here — send a PR*\n\n---\n\n## Roadmap\n\n- [ ] Runtime UA list fetching (opt-in) so patches land without a dependency bump\n- [ ] First-class Mixpanel, Amplitude, Segment adapters\n- [ ] Vercel Marketplace one-click install\n- [ ] Pre-built PostHog dashboards (JSON export) for AI-vs-human, agent leaderboard, top-pages-per-agent\n- [ ] `createMarkdownMiddleware()` — a batteries-included Next.js middleware for the full agent-readiness stack\n\nFile a [feature request](https://github.com/apideck-libraries/agent-analytics/issues/new) if something's missing from your setup.\n\n---\n\n## Contributing\n\nPRs welcome — especially new UA signatures, adapters, and docs.\n\n```bash\ngit clone https://github.com/apideck-libraries/agent-analytics\ncd agent-analytics\nnpm install\nnpm test\n```\n\n### Releasing\n\nPublishing to npm is fully automated by two workflows:\n\n1. **`release.yml`** watches `package.json` on `main`. When the version field\n   bumps to something without a matching `v<version>` tag, it creates the\n   GitHub Release.\n2. **`publish.yml`** fires on `release: published`, runs typecheck + tests +\n   build, and publishes to npm with `--provenance` via OIDC trusted\n   publishing (no secrets required).\n\nSo cutting a release is just:\n\n```bash\n# Pick a level (patch | minor | major), or edit package.json directly.\nnpm version patch\ngit push\n```\n\nThe push lands on main, `release.yml` notices the new version, cuts the\nrelease, and `publish.yml` publishes. No CLI juggling, no secrets to manage.\n\nOIDC trusted publishing is configured at\n[npmjs.com/package/@apideck/agent-analytics/access](https://www.npmjs.com/package/@apideck/agent-analytics/access)\n— the GitHub repo + `publish.yml` workflow are registered as the sole\ntrusted publisher.\n\n## Credits\n\nBuilt on learnings from:\n\n- [Agentic Engine Optimization](https://addyosmani.com/blog/agentic-engine-optimization/) by Addy Osmani — the case for making sites agent-ready\n- [contentsignals.org](https://contentsignals.org) — the Content-Signal spec\n- [darkvisitors.com](https://darkvisitors.com) — maintained catalogue of AI user-agents we cross-reference\n\n## License\n\n[MIT](./LICENSE) © [Apideck](https://apideck.com)\n\n---\n\n<div align=\"center\">\n<sub>Built by <a href=\"https://apideck.com\">Apideck</a> — the unified API platform for integrations.</sub>\n</div>\n","readmeFilename":"README.md"}