GA4 top browsers
AI-referred site traffic broken out by browser — the top 10, ranked by sessions.
curl --request GET \
--url 'https://api.aiclicks.io/api/v1/ga4/top-browsers?domain_id=8f1d3c0a-2f9b-4c11-9b80-7a82e1f0c3f3&days=30' \
--header 'Authorization: Bearer ak_live_xxx'
import httpx, os
resp = httpx.get(
"https://api.aiclicks.io/api/v1/ga4/top-browsers",
params={"domain_id": "8f1d3c0a-2f9b-4c11-9b80-7a82e1f0c3f3", "days": 30},
headers={"Authorization": f"Bearer {os.environ['AICLICKS_API_KEY']}"},
)
resp.raise_for_status()
for row in resp.json()["data"]["items"]:
print(f"{row['sessions']:>6} {row['browser']}")
const url = new URL("https://api.aiclicks.io/api/v1/ga4/top-browsers");
url.searchParams.set("domain_id", "8f1d3c0a-2f9b-4c11-9b80-7a82e1f0c3f3");
url.searchParams.set("days", "30");
const resp = await fetch(url, {
headers: { Authorization: `Bearer ${process.env.AICLICKS_API_KEY}` },
});
const { data } = await resp.json();
for (const row of data.items) console.log(row.sessions, row.browser);
{
"data": {
"items": [
{ "browser": "Chrome", "sessions": 700 },
{ "browser": "Safari", "sessions": 300 },
{ "browser": "Edge", "sessions": 120 }
]
},
"domain_id": "8f1d3c0a-2f9b-4c11-9b80-7a82e1f0c3f3",
"days": 30,
"llm_source": null,
"generated_at": "2026-07-13T10:00:11.218Z"
}
{ "detail": "domain_id query parameter is required. List the domains this key can access with GET /api/v1/domains, then pass ?domain_id=<uuid>." }
{ "detail": "Invalid or revoked API key" }
{ "detail": "API access is not enabled for this team. Contact support@aiclicks.io." }
{ "detail": "Too many requests. Please try again later." }
The browsers the domain's AI-referred visitors arrive on, ranked by sessions descending and capped at the top 10. Useful as a QA signal — an unusual browser mix in AI-referred traffic can flag how a given assistant renders or proxies its outbound links.
Each row is a browser and its AI-referred session count over the window.
domain_id is a required query parameter. Use `` to discover which domains the calling key can access. When the domain has no connected GA4 property (or no AI-referred traffic in the window), items is empty with a 200.
Authorizations
Your API key formatted as Bearer ak_live_<your-key>. Create one in the dashboard under Settings → Developers.
Optional UUID for log correlation. If omitted, we generate one and echo it back in the response.
Query parameters
UUID of the domain. Find domains via ``. Omitting this returns 400.
Trailing look-back window, 1–365. Defaults to 30.
Optional. Restrict to a single AI/LLM referral source — chatgpt, perplexity, claude, gemini, copilot, … Omit for all sources combined.
Response
The list payload.
One row per browser, sorted by sessions descending and capped at 10.
Browser name as reported by GA4 (e.g. Chrome, Safari).
AI-referred sessions on that browser during the window.
Echo of the requested domain.
Echo of the requested window.
Echo of the requested llm_source filter, or null when unset.
ISO-8601 timestamp of when the server produced (or cached) this response.
Response headers
| Header | Description |
|---|---|
X-Cache | HIT or MISS. Whether the response came from cache. |
X-Request-Id | Unique request id. Echoes incoming if you set one. |
X-RateLimit-Limit | Max requests per minute for this key. |
X-RateLimit-Remaining | Requests remaining in the current minute. |
X-RateLimit-Reset | Unix epoch seconds when the window resets. |
Caching
Cached for a short window per (domain_id, days, llm_source). Freshly synced GA4 data appears after the TTL expires.
Empty result
{
"data": { "items": [] },
"domain_id": "8f1d3c0a-2f9b-4c11-9b80-7a82e1f0c3f3",
"days": 30,
"llm_source": null,
"generated_at": "2026-07-13T10:00:11.218Z"
}