Agent Analytics

Get AI Referrals

Changed on

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.

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
    • API key in header X-API-Key
    • or API key in query parameter api_key
    • or HTTP bearer

Query parameters

project_idstring

Required if using a company api key

Example:or_f45b94ba-5e35-4982-93ed-285e72ee14eb
start_datestring date required

Inclusive bound, as full-date notation per RFC 3339 section 5.6. Required. A range spans at most 366 days.

Example:2026-09-22
end_datestring date required

Inclusive bound, as full-date notation per RFC 3339 section 5.6. Required. A range spans at most 366 days.

Example:2026-09-22
group_bystring[]

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.

[
  "assistant"
]
metricsstring[]

Metrics to return. Defaults to all of them, minus session_starts when grouping by event_name. Unrequested metrics are left out of the query.

[
  "session_starts",
  "conversions"
]
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.

Example:week
assistantsstring[]

Filter by assistant display name. An unrecognised name is rejected rather than ignored.

[
  "ChatGPT"
]
sourcesstring[]

Filter by raw GA4 sessionSource host.

[
  "chatgpt.com"
]
countriesstring[]

Filter by ISO 3166-1 alpha-2 country code.

[
  "DE"
]
mediumsstring[]

Filter by GA4 session medium. Use ai-assistant to isolate traffic identified by medium rather than by a known referrer host.

[
  "ai-assistant"
]
devicesstring[]

Filter by device category. Property-specific and case-sensitive: an unmatched value yields zeros rather than an error.

[
  "mobile"
]
event_namesstring[]

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.

[
  "purchase"
]
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.

Example:session_starts
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.

Example:false
limitinteger
offsetinteger

Response

Success

columnsstring[] required

Column order for the rows, derived from the request so a zero-row answer still carries its shape.

total_countnumber nullable required

Number of grouped rows the filters match — not a sum of any metric. Null when include_total_count was false.

currencystring nullable required

Reporting currency of revenue, null when revenue was not requested. Values are not converted, so revenue is not comparable across projects.

Example response

{
  "data": [
    {
      "assistant": "ChatGPT",
      "platform": "OpenAI",
      "source": "chatgpt.com",
      "medium": "referral",
      "country": "DE",
      "device": "mobile",
      "event_name": "page_view",
      "landing_page": "/pricing",
      "page_path": "/blog/*/overview",
      "host": "www.example.com",
      "time_bucket": "2026-03-01",
      "events": 4820,
      "session_starts": 1402,
      "conversions": 37,
      "revenue": 4210.5
    }
  ],
  "columns": [
    "assistant",
    "session_starts"
  ],
  "total_count": 12,
  "currency": "EUR"
}

Changes