Set up Custom Traffic (first-party collector)
Install the PingAura analytics collector to capture first-party pageviews, AI referrals, and bot crawls for your domain.
Custom Traffic is PingAura's first-party analytics collector. You send pageview events from your own server, and PingAura classifies them into human pageviews, AI-assistant referrals (ChatGPT, Perplexity, Gemini, and more), and AI bot crawls — then attributes them to your content. Unlike the GA4, Search Console, and Cloudflare connectors, this is data you own end to end: there is no third-party platform in the path.
Before you begin
- Your domain is added to PingAura (the same domain you will send events for).
- Custom Traffic is available on the Enterprise plan. If you don't see the tab, contact your account team.
- You can add a few lines to your site's server (Next.js, Node, or a Cloudflare Worker, any other framework, etc).
Step 1 — Create an ingest key
- Go to Settings → API Keys.
- Create a new key with the write scope.
- Copy the key immediately — it is shown only once. Store it as an environment variable (for example
PINGAURA_INGEST_KEY); never commit it.
An ingest key is a write-scoped API key. Keep it on your server — it is not a public browser key.
Step 2 — Confirm your domain
Events carry the domain they belong to. It must match a domain registered on your PingAura account exactly (for example example.com). If the domain isn't registered, the events are rejected.
Step 3 — Install the SDK
Install the collector package:
npm install @pingaura/custom-traffic-node
Pick the entry point for your stack. Each takes the same config: your ingest key and your registered domain.
Next.js
import { createAnalyticsMiddleware } from '@pingaura/custom-traffic-node/next';
export const track = createAnalyticsMiddleware({
writeKey: process.env.PINGAURA_INGEST_KEY,
domain: 'example.com',
});
Node / Express
import { analyticsMiddleware } from '@pingaura/custom-traffic-node/node';
app.use(
analyticsMiddleware({
writeKey: process.env.PINGAURA_INGEST_KEY,
domain: 'example.com',
}),
);
Cloudflare Worker
trackEdge is fire-and-forget: it reads only headers, never consumes the body, and never throws.
import { trackEdge } from '@pingaura/custom-traffic-node/cloudflare';
export default {
async fetch(request, env, ctx) {
const response = await fetch(request);
trackEdge(request, response, ctx, {
writeKey: env.PINGAURA_INGEST_KEY,
domain: 'example.com',
});
return response;
},
};
Any other server
import { createClient } from '@pingaura/custom-traffic-node';
const analytics = createClient({
writeKey: process.env.PINGAURA_INGEST_KEY,
domain: 'example.com',
});
await analytics.pageView({ url: request.url });
On a serverless runtime, keep the await so the event is sent before the function freezes (it's capped by the SDK's request timeout). On a long-running server (e.g. Express), you can drop the await to keep it fully fire-and-forget — pageView() never throws.
Don't see your framework or language?
The SDK covers Node, Next.js, and Cloudflare Workers, plus a generic client for any other JavaScript or TypeScript server.
Want a first-class SDK for your stack? Tell us which framework or language you'd like us to support and we'll prioritise it. Request framework support →
Step 4 — Deploy and verify
- Deploy your server with the ingest key set.
- Visit a few pages on your site.
- Open the Custom Traffic tab in PingAura. Once the first events land, the setup panel is replaced by your dashboard. First data usually appears within a minute.
Troubleshooting
If events aren't arriving, check these in order:
- Ingest key — make sure it's valid, not revoked, and has the write scope. If in doubt, create a new one.
- Plan — Custom Traffic must be enabled on your plan. If it isn't, contact your account team.
- Domain — the
domainyou send must match a domain registered on your account exactly. Watch for typos andwww/subdomain differences. - Send rate — sending a very high volume from one source can be throttled. Back off and retry.
The dashboard counts unique events, so safe retries won't double-count.