---
title: "Get AI Referrals"
method: GET
path: "/agent-analytics/google-analytics/referrals"
tags: ["Agent Analytics"]
---

# Get AI Referrals

`GET /agent-analytics/google-analytics/referrals`

## Request

- Base URL: `https://api.peec.ai/customer/v1`
- URL: `https://api.peec.ai/customer/v1/agent-analytics/google-analytics/referrals`
- Auth: one of:
  - API key in header `X-API-Key`
  - API key in query parameter `api_key`
  - HTTP bearer

AI-referral traffic from the project's connected Google Analytics property, scoped to the hosts the project owns and to referrals from AI assistants. There is no way to ask this endpoint for non-AI traffic.

To list the values a dimension takes, pass it as the only `group_by` and read the rows — that is how you discover event names, countries, pages and the assistants that actually sent traffic. When populating a filter, do not filter by the dimension you are listing, or the options the user has not already picked disappear.

Metric definitions, because the names are shorter than the meanings:
- `events`: GA4 event count.
- `session_starts`: GA4 `session_start` events, which is not GA4's `sessions` metric. Most are visits that entered on the site; the rest resumed there after idling past GA4's session timeout. It cannot be combined with `group_by=event_name`.
- `conversions`: GA4 key events, so one visit can contribute several, and which events count follows whatever the property marked as a key event.
- `revenue`: GA4 purchase revenue in the property's reporting currency, returned as `currency`.

Unknown dimension values come back as `(not set)`. It is a real row, and the free-string filters (`sources`, `devices`, `event_names`, `mediums`) accept it back; `countries` does not, because it takes ISO codes only. Figures are a lower bound on AI referrals: only referrer-visible traffic reaches GA4, so native apps and no-referrer policies land as Direct, and Gemini is often folded into Organic Search.

## Query parameters

- `project_id` string: Required if using a company api key
- `start_date` string, date, required: Inclusive bound, as full-date notation per RFC 3339 section 5.6. Required. A range spans at most 366 days.
- `end_date` string, date, required: Inclusive bound, as full-date notation per RFC 3339 section 5.6. Required. A range spans at most 366 days.
- `group_by` string[]: Dimension(s) to break the numbers down by, at most 3. Omit for period totals only. Pass a single dimension to list the values it takes.
- `metrics` string[]: Metrics to return. Defaults to all of them, minus session_starts when grouping by event_name. Unrequested metrics are left out of the query.
- `time_bucket` 'day' | 'week' | 'month': Adds a time_bucket column holding the bucket's start date. There is no hourly bucket: the source data is daily. Buckets at either end of the range cover only the days inside it.
- `assistants` string[]: Filter by assistant display name. An unrecognised name is rejected rather than ignored.
- `sources` string[]: Filter by raw GA4 sessionSource host.
- `countries` string[]: Filter by ISO 3166-1 alpha-2 country code.
- `mediums` string[]: Filter by GA4 session medium. Use `ai-assistant` to isolate traffic identified by medium rather than by a known referrer host.
- `devices` string[]: Filter by device category. Property-specific and case-sensitive: an unmatched value yields zeros rather than an error.
- `event_names` string[]: Filter by GA4 event name. Property-specific: a name this property never sends yields zeros rather than an error, so discover them with `group_by=event_name` first.
- `order_by` 'events' | 'session_starts' | 'conversions' | 'revenue' | 'time_bucket': Field to sort by, which must be one of the requested metrics (or time_bucket when it is set). Defaults to the first requested metric.
- `order_direction` 'asc' | 'desc'
- `include_total_count` 'true' | 'false': Set false to skip total_count. Counting is a second pass over the same rows, so it doubles the cost of the call.
- `limit` integer
- `offset` integer

## Response `200`

Success

- object: Success
  - `data` object[], required
    - `assistant` string
    - `platform` string
    - `source` string
    - `medium` string
    - `country` string
    - `device` string
    - `event_name` string
    - `landing_page` string: The session's entry page, repeated on every event in that session. Query string stripped.
    - `page_path` string: The page the event fired on. Query string stripped and UUIDs collapsed to `*`, so it does not join to landing_page.
    - `host` string
    - `time_bucket` string: First day of the bucket this row covers, always a plain date. Present only when the `time_bucket` request parameter was set, which names the width rather than a date.
    - `events` number
    - `session_starts` number
    - `conversions` number
    - `revenue` number
  - `columns` string[], required: Column order for the rows, derived from the request so a zero-row answer still carries its shape.
  - `total_count` number, nullable, required: Number of grouped rows the filters match — not a sum of any metric. Null when include_total_count was false.
  - `currency` string, nullable, required: Reporting currency of `revenue`, null when revenue was not requested. Values are not converted, so revenue is not comparable across projects.

## Other responses

- `409`: Response for status 409

## Changes

- **2026-11-03** `9fdffdff48a5`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/peec/apis/peec-ai-customer-api/changes/agent-analytics/google-analytics/referrals/get.md)

---

[API](https://skmtc.dev/peec/apis/peec-ai-customer-api.md) - [All operations](https://skmtc.dev/peec/apis/peec-ai-customer-api/llms.txt) - [OpenAPI document](https://skmtc.dev/peec/apis/peec-ai-customer-api/revisions/9d774600c8eb?raw)
