Query live GA4 with metrics, dimensions, filters and comparison
/sites/{site_id}/ga4/queryanalytics:readRead live GA4, scoped to the granted site hostname/path. Metrics and dimensions are comma-separated names. filters is a JSON array of {field,operator,value}; operators are EXACT, CONTAINS, BEGINS_WITH, ENDS_WITH. All filters are AND-combined with the mandatory site scope. Comparisons return independent exact reports; never sum distinct users across rows. Uses Google quota but no Satellite credits. keyEvents is canonical; conversions is accepted as an alias. Uses Google live reports and returns separate current/comparison tables. keyEvents is canonical and conversions is an alias. Each period consumes a property/provider request; no Satellite credits are charged. Maximum interval is 366 completed days. Do not sum daily/page distinct users into interval totals.
| Request | GET https://satelliteai.io/api/v1/sites/{site_id}/ga4/query |
| Permission | analytics:read |
| Response | A single object: data is Ga4QueryData. |
| Operation ID | queryGa4 |
More context and worked examples are in the developer guide.
Example request
curl --fail-with-body --get \
'https://satelliteai.io/api/v1/sites/123/ga4/query' \
--data-urlencode 'start_date=2026-10-01' \
--data-urlencode 'end_date=2026-10-07' \
-H "Authorization: Bearer $SATELLITE_API_KEY"Replace the example IDs with values returned by the discovery endpoints. Example values are placeholders, not real records.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
site_idrequired | path | integer | Authorized site id. Parent and site grants must also match. min 1 · max 9223372036854775807 |
start_daterequired | query | string (date) | Inclusive YYYY-MM-DD date. Supply both endpoints of an ordered interval; no future dates. At most 366 completed property-local days. |
end_daterequired | query | string (date) | Inclusive YYYY-MM-DD date. Supply both endpoints of an ordered interval; no future dates. At most 366 completed property-local days. |
metrics | query | string | Comma-separated 1–10 Google metric names. Default sessions,totalUsers,keyEvents. conversions is normalized to keyEvents. Duplicate names are rejected. default sessions,totalUsers,keyEvents · max length 1500 |
dimensions | query | string | Comma-separated 0–9 Google dimension names; omitted means no dimensions. Duplicate names are rejected. max length 1500 |
filters | query | string | JSON array of 1–10 AND-combined dimension filters with exactly field, operator and value. Operators: EXACT, CONTAINS, BEGINS_WITH, ENDS_WITH (case insensitive). Values are 1–1000 characters. Mandatory site hostname/path constraints are always applied. max length 12000 |
comparison | query | string | none, previous_period (same length immediately before current), previous_year, or custom. A comparison makes a second Google report call. one of: none, previous_period, previous_year, custom · default none |
compare_start_date | query | string (date) | Required together with compare_end_date only for comparison=custom. Ordered interval at most 366 completed days. |
compare_end_date | query | string (date) | Required together with compare_start_date only for comparison=custom. |
limit | query | integer | Maximum rows per page. Default 100, maximum 100. default 100 · min 1 · max 100 |
offset | query | integer | Zero-based row offset, default 0, maximum 100000. default 0 · min 0 · max 100000 |
Unknown or repeated query parameters return 400.
Data dictionary
Scoped result. Lists return pagination metadata; unavailable records return 404.
[] marks an array element. nullable means the value can be null; treat it as unknown, not zero. always present means the key is always included in the object.
| Field | Type | Description |
|---|---|---|
data.site_id | integer | Granted Satellite site. |
data.source | string | one of: live |
data.metrics | array of string | Canonical metric names. conversions becomes keyEvents. |
data.dimensions | array of string | |
data.current | object | One exact Google report. row_count is the provider total before limit/offset. |
data.current.start_date | stringnullable | Start date. |
data.current.end_date | stringnullable | End date. |
data.current.row_count | integernullable | Row count. |
data.current.rows | array of map of string | Dimension and metric values keyed by the requested canonical names. Metric values are strings. |
data.current.metadata | object | Google report metadata, including timezone, quality, sampling or threshold information when supplied. |
data.comparison | objectnullable | Separate comparison report; null for comparison=none. No calculated deltas are added. |
data.comparison.start_date | stringnullable | Start date. |
data.comparison.end_date | stringnullable | End date. |
data.comparison.row_count | integernullable | Row count. |
data.comparison.rows | array of map of string | Dimension and metric values keyed by the requested canonical names. Metric values are strings. |
data.comparison.metadata | object | Google report metadata, including timezone, quality, sampling or threshold information when supplied. |
data.metric_aliases | object | |
data.metric_aliases.conversions | string | one of: keyEvents |
data.credits_charged | integer | Satellite credits charged. one of: 0 |
Response metadata
| Field | Type | Description |
|---|---|---|
meta.request_id | stringalways present | Request identifier; also returned in X-Request-ID. Include it in support requests. |
meta.api_version | stringalways present | API version that produced the response. one of: v1 |
meta.limit | integer | Maximum records per page applied to this request. min 1 · max 100 |
meta.has_more | boolean | True when another page is available. |
meta.next_cursor | stringnullable | Opaque cursor for the next page; send as cursor. Null on the last page. |
meta.availability | string | available when stored data exists; not_available when it does not. one of: available, not_available |
meta.billing | object | Present for paid live SERP requests; replayed receipts describe the original debit, not an additional charge. |
meta.billing.operation | stringalways present | one of: client_api_serp_refresh |
meta.billing.credits_charged | integeralways present | min 0 |
meta.billing.transaction_id | integeralways present | |
meta.billing.replayed | booleanalways present |
Error responses
Errors return {"error": {"code", "message", "request_id"}}. See error handling for retry guidance.
| HTTP | When |
|---|---|
400 | Invalid parameters |
401 | Invalid credentials |
403 | Missing permission |
404 | Missing or inaccessible resource |