Skip to main content

Connecting to Traffic Analytics using a custom integration

Written by Alp Aysan
Updated over 4 months ago

Step 1: Access Traffic Analytics

Navigate to Traffic Analytics in your Cognizo dashboard and select custom integrations.


Step 2: Setup a non-blocking backend hook

Insert a lightweight call to Cognizo in your global middleware (or equivalent) so it runs on every request you want to observe (public pages, API endpoints). The call should be asynchronous and fire-and-forget with a short timeout (1–2s) so it never slows down real users.

Copy tracking_api_url and tracking_code from Cognizo and use the request below to start sending requests.

Required fields to send:

  • user_agent: From request headers

  • ip_address: See IP Address Priority below

Optional (recommended): url, referer, country, cf_ray, method

Minimal example:

curl -X POST "{tracking_api_url}/track/{tracking_code}" \
-H "Content-Type: application/json" \
-d '{
"user_agent": "Mozilla/5.0 AppleWebKit/537.36 (compatible; GPTBot/1.0)",
"ip_address": "23.98.142.177",
"url": "https://yourapp.com/pricing",
"referer": "https://google.com",
"country": "US"
}'

More examples can be found below.


Step 3: Verify Setup

Return to Cognizo and click "Verify" to complete your setup and confirm the integration is working correctly.


API Reference

Endpoint

POST {tracking_api_url}/track/{tracking_code}

Body Parameters

  • user_agent (required) — Client’s User-Agent header

  • ip_address (required) — Client’s IP address

  • url (optional) — Page URL being visited

  • referer (optional) — Referrer URL

  • country (optional) — Country code (e.g., "US")

  • cf_ray (optional) — Cloudflare Ray ID

  • method (optional) — HTTP method (e.g., "GET")

Success Response

{
"status": "success",
"is_bot": true,
"bot_type": "OpenAI",
"confidence": 99
}

IP Address Priority

We recommend extracting the client IP in this order:

  1. X-Forwarded-For (first IP)

  2. X-Real-IP

  3. RemoteAddr

// Example
const clientIP = req.headers['x-forwarded-for']?.split(',')[0].trim()
|| req.headers['x-real-ip']
|| req.socket.remoteAddress;

Best Practices

Do:

  • Use async / non-blocking requests

  • Set short timeouts (1–2 seconds)

  • Fail silently (catch and ignore errors)

  • Extract IP from X-Forwarded-For first

  • Skip noisy paths like /health and /metrics

Don’t:

  • Block request handling while tracking

  • Throw errors if tracking fails

  • Send sensitive headers (Authorization, Cookie)

  • Track internal/admin-only endpoints


Examples

Node.js/Express

const axios = require('axios');

app.use(async (req, res, next) => {
const clientIP = req.headers['x-forwarded-for']?.split(',')[0]?.trim()
|| req.headers['x-real-ip']
|| req.socket.remoteAddress;
const userAgent = req.headers['user-agent'] || 'Unknown';
const pageURL = `${req.protocol}://${req.get('host')}${req.originalUrl}`;
const referer = req.headers['referer'] || '';

axios.post('{tracking_api_url}/track/{tracking_code}', {
user_agent: userAgent,
ip_address: clientIP,
url: pageURL,
referer: referer
}, {
headers: { 'Content-Type': 'application/json' },
timeout: 2000,
// Avoid retries; this call should be best-effort only
validateStatus: () => true
}
).catch(() => {});

next();
});

Go

import (
"bytes"
"encoding/json"
"net/http"
"time"
)

type TrackingPayload struct {
UserAgent string `json:"user_agent"`
IPAddress string `json:"ip_address"`
URL string `json:"url"`
Referer string `json:"referer"`
}

func trackRequest(r *http.Request) {
clientIP := r.Header.Get("X-Forwarded-For")
if clientIP == "" {
clientIP = r.Header.Get("X-Real-IP")
if clientIP == "" {
clientIP = r.RemoteAddr
}
}

payload := TrackingPayload{
UserAgent: r.Header.Get("User-Agent"),
IPAddress: clientIP,
URL: r.URL.String(),
Referer: r.Header.Get("Referer"),
}

jsonData, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST", "{tracking_api_url}/track/{tracking_code}", bytes.NewBuffer(jsonData))
req.Header.Set("Content-Type", "application/json")

client := &http.Client{Timeout: 2 * time.Second}
go func() { _, _ = client.Do(req) }() // fire-and-forget
}

Python

import httpx

async def track_request(request):
client_ip = (request.headers.get("x-forwarded-for", "").split(",")[0].strip()
or request.headers.get("x-real-ip")
or request.client.host)
user_agent = request.headers.get("user-agent", "Unknown")
page_url = str(request.url)
referer = request.headers.get("referer", "")

payload = {
"user_agent": user_agent,
"ip_address": client_ip,
"url": page_url,
"referer": referer
}

async with httpx.AsyncClient(timeout=2.0) as client:
try:
await client.post(
"{tracking_api_url}/track/{tracking_code}",
json=payload,
headers={"Content-Type": "application/json"}
)
except Exception:
pass

PHP

use Illuminate\Support\Facades\Http;

public function handle(Request $request, Closure $next)
{
$clientIP = $request->header('X-Forwarded-For')
? explode(',', $request->header('X-Forwarded-For'))[0]
: ($request->header('X-Real-IP') ?: $request->ip());

Http::timeout(2)->post('{tracking_api_url}/track/{tracking_code}', [
'user_agent' => $request->userAgent(),
'ip_address' => $clientIP,
'url' => $request->fullUrl(),
'referer' => $request->header('Referer', '')
]);

return $next($request);
}

Ruby / Rails

require 'net/http'
require 'json'

def track_request(request)
Thread.new do
begin
client_ip = request.env['HTTP_X_FORWARDED_FOR']&.split(',')&.first&.strip ||
request.env['HTTP_X_REAL_IP'] ||
request.ip

payload = {
user_agent: request.user_agent,
ip_address: client_ip,
url: request.url,
referer: request.referer
}

uri = URI('{tracking_api_url}/track/{tracking_code}')
Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https', read_timeout: 2) do |http|
req = Net::HTTP::Post.new(uri)
req['Content-Type'] = 'application/json'
req.body = payload.to_json
http.request(req)
end
rescue StandardError
# swallow errors
end
end
end

Java / Spring Boot

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.databind.ObjectMapper;

private void trackRequest(HttpServletRequest request) {
new Thread(() -> {
try {
String clientIP = request.getHeader("X-Forwarded-For");
if (clientIP == null || clientIP.isBlank()) clientIP = request.getHeader("X-Real-IP");
if (clientIP == null || clientIP.isBlank()) clientIP = request.getRemoteAddr();

Map<String, String> payload = new HashMap<>();
payload.put("user_agent", request.getHeader("User-Agent"));
payload.put("ip_address", clientIP);
payload.put("url", request.getRequestURL().toString());
String json = new ObjectMapper().writeValueAsString(payload);

HttpClient client = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(2))
.build();

HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("{tracking_api_url}/track/{tracking_code}"))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(json))
.timeout(Duration.ofSeconds(2))
.build();

client.send(req, HttpResponse.BodyHandlers.discarding());
} catch (Exception ignored) {}
}).start();
}

Did this answer your question?