Google Analytics ExecModule
Overview
GoogleAnalyticsModule connects ValkyrAI workflows to the Google Analytics Data API through the native map I/O ExecModule ABI. It runs bounded GA4 standard, realtime, pivot, and batch reports, retrieves property metadata, and checks dimension and metric compatibility without exposing OAuth credentials to workflow data.
The connector uses only analyticsdata.googleapis.com. Every exposed operation is read-only at the provider, so transient HTTP and network failures may receive bounded retries. The module does not create properties, change account settings, manage audiences, send Measurement Protocol events, or mutate Analytics data.
Usage
- Enable the Google Analytics Data API in the Google Cloud project that owns the OAuth client.
- Authorize a dedicated Google principal with
https://www.googleapis.com/auth/analytics.readonlyand access to the target GA4 property. - Store the numeric GA4 property ID in
IntegrationAccount.accountIdand a short-lived OAuth access token in the encryptedapiKeySecureField. - Set the IntegrationAccount to
READYand bind it throughExecModuleConfig.authConfig.integrationAccount. - Start with
get_metadata, then build reports using returned dimension and metric API names. - Use
limit,offset, filters, and date ranges to keep reports bounded and composable.
Workflow input cannot provide an authorization header, arbitrary API host, refresh token, service-account private key, account administration operation, or data mutation.
Inputs
| Name | Type | Requirement | Default | Description and constraints |
|---|---|---|---|---|
operation | string | Required | None | One of the seven documented operations. |
propertyId | string | Optional | IntegrationAccount.accountId | Numeric GA4 property ID, 1–20 digits. |
dateRanges | array | Standard and pivot reports | None | 1–4 {startDate,endDate,name?} objects. Dates accept ISO YYYY-MM-DD, today, yesterday, or NdaysAgo. |
dimensions | array | Report dependent | None | Up to 9 {name} definitions using GA4 API names. |
metrics | array | Report dependent | None | Up to 10 {name} definitions using GA4 API names. |
dimensionFilter | object | Optional | None | Provider-shaped dimension filter expression, capped at 128 KiB. |
metricFilter | object | Optional | None | Provider-shaped metric filter expression, capped at 128 KiB. |
orderBys | array | Optional | None | Up to 10 provider ordering definitions. |
pivots | array | Pivot reports | None | 1–2 pivot definitions; each requires non-empty fieldNames. |
requests | array | Batch reports | None | 1–5 provider-shaped report requests. Each request is independently bounded. |
metricAggregations | array | Optional | None | Any of TOTAL, MINIMUM, MAXIMUM, or COUNT. |
currencyCode | string | Optional | Property default | Three-letter ISO-4217 currency code. |
limit | integer | Optional | 1000 | Maximum requested and normalized rows, 1–100,000. |
offset | integer | Optional | 0 | Provider row offset, 0–100,000,000. |
simplify | boolean | Optional | true | Maps standard, realtime, and pivot rows by returned header name. |
keepEmptyRows | boolean | Optional | false | Asks GA4 to retain rows whose metrics are all zero. |
returnPropertyQuota | boolean | Optional | false | Includes provider quota state when supported. |
maxAttempts | integer | Optional | 3 | Maximum attempts for logically read-only requests, 1–10. |
timeoutMs | integer | Optional | 30000 | HTTP timeout, 100–300,000 ms. |
Outputs
| Name | Type | When present | Description |
|---|---|---|---|
status | string | Always | success or error. |
operation | string | Always | Normalized operation. |
httpStatus / attempts | integer | Provider request | HTTP status and attempts consumed. |
items / count | array / integer | Simplified single report | Rows mapped by returned dimension and metric header names. |
rowCount | integer | Single report | Provider count before local output bounding. |
propertyQuota | object | Requested and returned | GA4 property quota details. |
data | object | Raw, batch, metadata, or compatibility result | Provider-shaped response when simplification does not apply. |
error | object | Failure | Safe {code,message,httpStatus?,retryable} details. |
OAuth tokens and authorization values are redacted from errors, logs, outputs, and workflow events.
IntegrationAccount Requirements
| Setting | Requirement |
|---|---|
| Provider | Google OAuth principal with Google Analytics Data API access |
accountName | Human-readable automation identity |
accountId | Numeric GA4 property ID, for example 123456789 |
apiKey | Encrypted SecureField containing a short-lived OAuth access token |
| OAuth scope | https://www.googleapis.com/auth/analytics.readonly |
status | Exactly READY |
Grant the principal Viewer access only to the required Analytics account or property. Token issuance, rotation, revocation, and refresh remain IntegrationAccount lifecycle responsibilities.
Configuration
{
"version": "1.0.0",
"authConfig": {
"authStrategy": 1,
"integrationAccount": "integration-account:google-analytics-production"
},
"retryPolicy": {
"maxAttempts": 3,
"backoffStrategy": "EXPONENTIAL",
"initialDelayMs": 1000,
"maxDelayMs": 60000
},
"payloadConfig": {
"parameters": "{\"operation\":\"run_report\",\"limit\":1000,\"simplify\":true}"
}
}
The integration-account reference is symbolic. Persisted workflows use the generated relationship and never plaintext access tokens.
Operations
| Operation | Google Analytics behavior | Side effect |
|---|---|---|
run_report | Runs one standard GA4 report with date ranges, dimensions, metrics, filters, ordering, aggregation, offset, and limit. | Read-only. |
run_realtime_report | Runs one realtime report without date ranges. | Read-only. |
batch_run_reports | Runs 1–5 standard reports for the same property. | Read-only. |
run_pivot_report | Runs one standard-date pivot report with 1–2 pivot definitions. | Read-only. |
batch_run_pivot_reports | Runs 1–5 pivot reports for the same property. | Read-only. |
get_metadata | Retrieves dimension and metric metadata for the property. | Read-only. |
check_compatibility | Checks whether selected dimensions and metrics can be combined. | Read-only. |
Errors and Failure Modes
| Code | Typical cause | Retryable | Resolution |
|---|---|---|---|
VALIDATION_ERROR | Missing property, malformed date range, invalid field name, oversized filter/payload, or absent report requirement. | No | Correct the named input; no request was sent. |
UNSUPPORTED_OPERATION | Unknown operation. | No | Select a documented operation. |
INTEGRATION_ACCOUNT_REQUIRED | No bound account. | No | Bind a Google Analytics IntegrationAccount. |
INTEGRATION_ACCOUNT_NOT_READY | Account is not READY. | No | Repair or reconnect the account. |
GOOGLE_ANALYTICS_UNAUTHENTICATED / GOOGLE_ANALYTICS_HTTP_401 | Expired, revoked, or invalid OAuth access token. | No | Refresh the IntegrationAccount token. |
GOOGLE_ANALYTICS_PERMISSION_DENIED / GOOGLE_ANALYTICS_HTTP_403 | The principal lacks property access or required scope. | No | Grant the minimum missing property permission or scope. |
GOOGLE_ANALYTICS_NOT_FOUND / GOOGLE_ANALYTICS_HTTP_404 | Property ID is wrong or unavailable to the principal. | No | Verify the numeric property ID and access assignment. |
GOOGLE_ANALYTICS_RESOURCE_EXHAUSTED / GOOGLE_ANALYTICS_HTTP_429 | Property or project quota is exhausted. | Yes | Honor Retry-After, reduce concurrency, and inspect property quota output. |
GOOGLE_ANALYTICS_HTTP_5xx | Transient provider failure. | Yes | Retry with bounded backoff. |
NETWORK_ERROR | Timeout, DNS, TLS, or connectivity failure. | Yes | Verify connectivity and retry later. |
RESPONSE_TOO_LARGE | Provider response exceeded 10 MiB. | No | Lower limit, narrow filters, or continue with a larger offset. |
Example
Report active users by country for the last seven days:
{
"operation": "run_report",
"dateRanges": [
{"startDate": "7daysAgo", "endDate": "today", "name": "current"}
],
"dimensions": [
{"name": "country"}
],
"metrics": [
{"name": "activeUsers"},
{"name": "sessions"}
],
"orderBys": [
{"metric": {"metricName": "activeUsers"}, "desc": true}
],
"limit": 100,
"simplify": true
}
Expected result:
{
"status": "success",
"operation": "run_report",
"httpStatus": 200,
"rowCount": 2,
"count": 2,
"items": [
{"country": "United States", "activeUsers": "42", "sessions": "51"},
{"country": "Canada", "activeUsers": "17", "sessions": "22"}
],
"attempts": 1
}
Notes
- Pagination: the Data API uses
limitandoffset, not an opaque page token. Continue withoffset + countwhile holding property, dates, dimensions, metrics, filters, ordering, and currency constant. The connector returns one bounded page per invocation. - Rate limits: every operation is provider read-only, including report
POSTcalls. HTTP 408, 429, 500, 502, 503, and 504 and network failures may retry up tomaxAttempts, honoring numeric or RFC-1123Retry-Aftervalues and bounded exponential backoff. - API limits: requests are capped at 512 KiB, responses at 10 MiB, standard reports at 4 date ranges, 9 dimensions, 10 metrics, 10 orderings, 100,000 rows, pivot reports at 2 pivots, and batches at 5 reports.
- Idempotency: all exposed calls are read-only and deterministic for a fixed property, request, and underlying Analytics state. Repeated realtime reports may naturally differ as new events arrive.
- Destructive behavior: none is exposed. Property/account administration, audience changes, data deletion, event ingestion, user-data collection, OAuth management, and Measurement Protocol writes are intentionally deferred.
- Privacy: report output can contain confidential analytics dimensions and metrics. Keep downstream workflows within the same access boundary, avoid unnecessary user-level dimensions, and apply Google Analytics data retention and consent requirements.
- API behavior: provider filters, pivots, comparisons, cohorts, sampling metadata, thresholding metadata, and quota objects remain provider-shaped. Use
get_metadataandcheck_compatibilitybefore constructing dynamic reports. - External verification: local tests cover fixed-host routing, OAuth headers, report shapes, date and field validation, normalized rows, batch/pivot bounds, retry, redaction, credential failures, and metadata discovery. Live property permissions, OAuth refresh, quotas, thresholding, cardinality, attribution, freshness, and report values require separately authorized Google Analytics credentials and are not exercised in repository tests.
- Functional references: n8n Google Analytics integration, Google Analytics Data API v1beta, and Data API schema reference.