google-analytics

$npx mdskill add zapier/connectors/google-analytics

Run Google Analytics reports and manage properties via API calls

  • Fetch analytics data for website traffic and user behavior.
  • Depends on OAuth-authenticated Data API and Admin API for reporting and configuration respectively.
  • Decides actions based on user queries about GA4 metrics, dimensions, events, and account management.
  • Delivers results through API calls, enabling further processing or integration with other systems.

SKILL.md

.github/skills/google-analyticsView on GitHub ↗
---
name: google-analytics
description: Agent-callable Google Analytics 4 (GA4) tools — run analytics reports, discover the dimensions and metrics a property supports, navigate accounts and properties, manage key events and custom dimensions/metrics, and send Measurement Protocol events. Use when the user mentions Google Analytics or GA4, or wants website/app traffic, conversion, or reporting data — including requests that don't name GA4 explicitly, e.g. how many users visited last week, top pages by country.
license: Elastic-2.0
compatibility: Run `npm install --omit=dev` in this directory, then `node cli.js`. The TypeScript source needs Node.js 22.18+; on older Node, run `cli.js` for build-it-yourself / prebuilt / alternative-runtime options.
metadata:
  source: https://github.com/zapier/connectors/blob/main/apps/google-analytics/SKILL.md
  title: Google Analytics
  api-docs: https://developers.google.com/analytics/devguides/reporting/data/v1
  zapier-app-key: GoogleAnalytics4CLIAPI
---

# Google Analytics

_Independent, unofficial connector for Google Analytics. Not affiliated with, endorsed by, or sponsored by Google Analytics. "Google Analytics" is a trademark of its owner, used only to identify the service this connector works with._

Google Analytics 4 (GA4) exposes two OAuth-authenticated APIs — the Data API for reporting and the Admin API for configuration — plus the Measurement Protocol for sending events. This connector wraps all three: run and explore analytics reports, discover the dimensions and metrics a property supports, walk the account → property tree, manage key events (conversions) and custom dimensions/metrics, and send server-side events. It is reporting-first — `runReport` is the core tool, with `getMetadata` and `checkCompatibility` underneath so you can compose a valid report without guessing field names.

Every property-scoped tool takes `propertyId` — the numeric GA4 property id (e.g. `123456`), **not** the `G-XXXXXXX` measurement id. Resolve it once with `listAccountSummaries`.

## When to use this

- **Reporting** — run historical (`runReport`) or realtime (`runRealtimeReport`) reports, discover valid dimension/metric names (`getMetadata`), and check whether a field combination is valid (`checkCompatibility`).
- **Navigation** — find which property to operate on and read its configuration (`listAccountSummaries`, `getProperty`, `listDataStreams`).
- **Key events (conversions)** — list, get, create, and delete the events GA4 counts as conversions.
- **Custom definitions** — list, create, and archive custom dimensions and custom metrics.
- **Measurement Protocol** — manage a data stream's send secrets and send server-side events (`listMeasurementProtocolSecrets`, `createMeasurementProtocolSecret`, `sendEvent`).

## Setup

This is an [agentskills.io](https://agentskills.io) skill.

**If this connector is already exposed to you as callable tools** (e.g. `mcp__google-analytics__<tool>`), that's a valid path — call them directly. Everything below is only for standalone terminal use when no such tools are loaded.

If the connector has not been installed as a skill yet, install it first with `npx skills zapier/connectors --skill google-analytics` (or your harness's own skill-install mechanism), then continue here.

The connector runs on **Node.js 22.18+** and needs a one-time `npm install` in this directory. `cli.js` is the entry point — list every script with `node cli.js --help`, then learn a script's inputs and connections with `node cli.js run <script> --help`. On older Node, run `node cli.js --help` anyway: it detects your runtime and prints how to run without upgrading (the prebuilt npm package, or another runtime) — don't skip the connector just because Node is old.

`cli.js` self-checks readiness before running: if dependencies aren't installed it exits non-zero with the exact install command (it disambiguates a read-only directory from a sandbox-blocked package cache). Run that, then re-run your command.

## Scripts

Every script uses the single `google-analytics` connection. Most take a numeric `propertyId` from `listAccountSummaries`.

| Script                                       | Script name                       | Connections      | Description                                                                                                          |
| -------------------------------------------- | --------------------------------- | ---------------- | -------------------------------------------------------------------------------------------------------------------- |
| `scripts/runReport.ts`                       | `runReport`                       | google-analytics | Run a GA4 report — dimensions + metrics over date ranges, optionally filtered/sorted. The core analytics tool.       |
| `scripts/runRealtimeReport.ts`               | `runRealtimeReport`               | google-analytics | Run a realtime report over roughly the last 30 minutes of activity. No date ranges.                                  |
| `scripts/getMetadata.ts`                     | `getMetadata`                     | google-analytics | List the dimensions and metrics a property supports, with API + UI names. Call before `runReport`.                   |
| `scripts/checkCompatibility.ts`              | `checkCompatibility`              | google-analytics | Check whether a set of dimensions and metrics can be combined in one report. Recovery for incompatible-field errors. |
| `scripts/listAccountSummaries.ts`            | `listAccountSummaries`            | google-analytics | List every accessible account with its properties. The entry point for resolving `propertyId`.                       |
| `scripts/getProperty.ts`                     | `getProperty`                     | google-analytics | Get a property's config — display name, currency, timezone, industry category.                                       |
| `scripts/listDataStreams.ts`                 | `listDataStreams`                 | google-analytics | List a property's data streams; web streams carry the `G-` measurement id.                                           |
| `scripts/listKeyEvents.ts`                   | `listKeyEvents`                   | google-analytics | List a property's key events (important business actions).                                                           |
| `scripts/getKeyEvent.ts`                     | `getKeyEvent`                     | google-analytics | Get one key event by id.                                                                                             |
| `scripts/createKeyEvent.ts`                  | `createKeyEvent`                  | google-analytics | Mark an event name as a key event (an important business action).                                                    |
| `scripts/deleteKeyEvent.ts`                  | `deleteKeyEvent`                  | google-analytics | Delete a key event (only ones with `deletable: true`). Destructive.                                                  |
| `scripts/listCustomDimensions.ts`            | `listCustomDimensions`            | google-analytics | List a property's custom dimensions.                                                                                 |
| `scripts/createCustomDimension.ts`           | `createCustomDimension`           | google-analytics | Create a custom dimension on an event/user parameter.                                                                |
| `scripts/archiveCustomDimension.ts`          | `archiveCustomDimension`          | google-analytics | Archive a custom dimension, freeing its slot (archive only — no delete method). Destructive.                         |
| `scripts/listCustomMetrics.ts`               | `listCustomMetrics`               | google-analytics | List a property's custom metrics.                                                                                    |
| `scripts/createCustomMetric.ts`              | `createCustomMetric`              | google-analytics | Create a custom metric on a numeric event parameter.                                                                 |
| `scripts/archiveCustomMetric.ts`             | `archiveCustomMetric`             | google-analytics | Archive a custom metric, freeing its slot (archive only — no delete method). Destructive.                            |
| `scripts/listMeasurementProtocolSecrets.ts`  | `listMeasurementProtocolSecrets`  | google-analytics | List a data stream's Measurement Protocol secrets, including their values.                                           |
| `scripts/createMeasurementProtocolSecret.ts` | `createMeasurementProtocolSecret` | google-analytics | Create a Measurement Protocol secret on a data stream.                                                               |
| `scripts/sendEvent.ts`                       | `sendEvent`                       | google-analytics | Send events to GA4 via the Measurement Protocol. Authenticates with a stream `apiSecret`, not OAuth.                 |

> **Measurement Protocol secrets — create and list only.** This connector can create and list Measurement Protocol secrets, but **cannot delete or rotate them**. To delete a secret, use the GA4 Admin UI: Admin → Data streams → (select stream) → Measurement Protocol API secrets.

## Disambiguation & refusals

**Resolving a property by name.** Tools take a numeric `propertyId`, not a name. Resolve it with `listAccountSummaries` and count _exact_ (case-insensitive) matches on `propertySummaries[].displayName`: exactly one match → use its `propertyId` and act; two or more that tie → stop, list the candidates with their `propertyId` (and parent account), and ask which one. Never silently pick. The same rule applies to resolving a `keyEventId` / `customDimensionId` / `customMetricId` / `dataStreamId` from the matching `list*` tool.

**Unsupported operations — say so and stop; don't substitute another tool.** This connector does **not** create or delete GA4 accounts or properties, manage user access/permissions, or read Universal Analytics (UA) data — and it exposes no funnel, pivot, cohort, or audience-export reports, and no audience or calculated-metric management. If asked for one of these, say it isn't supported rather than repurposing a different tool or reporting a success you didn't perform. (For a report the flat `runReport` can't express, say so — don't fake a pivot by post-processing rows.)

## Auth

Pass auth as one connection string with `--connection [<resolver>:]<value>`. The value is a selector, not the secret; the `<resolver>:` prefix is optional (a bare value goes to the first resolver that claims it). Each script declares the connections it needs and the resolvers each accepts — always run `node cli.js run <script> --help` to see them rather than relying on this file.

The connector uses a single connection, `google-analytics`, carrying a Google OAuth 2.0 access token sent as `Authorization: Bearer <token>`. The connection carries the full `analytics` scope — which the Data API accepts for reporting reads, alongside `analytics.readonly` — plus `analytics.edit` for the Admin write tools, so both read and write tools work with one connection. A read-only deployment can grant just `analytics.readonly`, in which case the write tools return `PERMISSION_DENIED`.

- **`zapier:<connection-id>`** _(recommended)_ — Zapier-managed auth: route through a Zapier Google Analytics connection and the Zapier auth, retries, and governance layer injects and transparently refreshes the token. Find the id with `npx zapier-sdk list-connections GoogleAnalytics4CLIAPI` (run `login` first if unauthenticated; add `--json` for machine output).
- **`env:GOOGLE_ANALYTICS_ACCESS_TOKEN`** _(fallback)_ — read a Google OAuth access token from that environment variable and send it as the bearer. The value is the env-var NAME, not the token. **Caveat: Google access tokens are short-lived and this resolver does NOT refresh them** — direct mode suits short-lived/testing use; the Zapier-managed connection refreshes automatically.

**`sendEvent` is the exception.** Its real credential is the per-call `apiSecret` input (a data stream's Measurement Protocol secret, from `listMeasurementProtocolSecrets`), not the connection. The OAuth token is still attached to the request but is not used by the Measurement Protocol endpoint, which authenticates via `api_secret` — so `sendEvent` still requires the `google-analytics` connection to be present.

## Running scripts

After `npm install`, run a script by name with `node cli.js run <script>`, or execute its file directly — both take the same arguments and both accept `--help`. Always run a script's `--help` first to learn its exact input schema and connections, then invoke it:

```bash
# default — via the entry point; self-checks readiness and prints friendly diagnostics
node cli.js run <script> '<input-json>' --connection [<resolver>:]<value>
# shorthand — runs the script file directly (same args, same Node 22.18+ need, no readiness check)
./scripts/<script>.ts '<input-json>' --connection [<resolver>:]<value>
```

When a harness can't execute scripts directly, fall back to MCP — `node cli.js mcp` serves every script as a tool over stdio. Register it as a local MCP server in your client: the stanza is harness-specific (an `mcpServers` entry in Claude Desktop, Cursor, Claude Code, …) with `command: "node"`, `args: ["cli.js", "mcp"]`, run from this directory. Run `node cli.js mcp --help` for auth options. Add the stanza yourself if you can edit the client's MCP config; otherwise guide the user. If a local server isn't possible, guide the user to use Zapier's remote MCP servers at <https://mcp.zapier.com> instead.

## Output format

Every script returns a `{ data, meta }` envelope:

- **`data`** — the script's result (the shape its `outputSchema` declares; run the script's `--help` to see that exact schema).
- **`meta.outputDataValidation`** — what validating `data` did:
  - `{ skipped: false, droppedPaths: null }` — validated, nothing removed.
  - `{ skipped: false, droppedPaths: [...], instruction }` — validated, but those paths were stripped from `data`: fields the script returned from the API that the `outputSchema` doesn't declare. If you need them, re-run with output validation skipped.
  - `{ skipped: true }` — validation was bypassed; `data` is the raw, unchecked script output.

**Reading dropped fields / `skipOutputDataValidation`.** To receive the raw, unvalidated result, append `--skipOutputDataValidation` to the script invocation. Input validation is never skipped.

**Trimming the result / `filterOutputData`.** To shrink a large result down to the fields you need, append `--filterOutputData '<jq>'` — a jq expression that post-processes `data`. The jq runs against `data` only, NOT the `{ data, meta }` envelope, so write it rooted at `data` (run the script's `--help` to see its output schema). The transformed value replaces `data`, `meta` is preserved, and the result is NOT re-validated against the output schema.

## References

| Reference                                                                                | When to load                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| ---------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [references/google-analytics-api-gotchas.md](references/google-analytics-api-gotchas.md) | Before or while calling any tool. Covers the error envelope + recovery table, the numeric `propertyId` rule, report row limits & paging, date-range/timezone rules, string metric values and their types, `(other)`-row and thresholding caveats, dimension vs metric filters, custom-dimension/metric scopes/units/limits and the archive-only removal, key-event vs conversion terminology, and the Measurement Protocol identity, payload limits, and no-error-codes/validation behavior. |
| [references/use-as-recipe.md](references/use-as-recipe.md)                               | Loaded by a harness writing its own code against the GA4 API (can't load the tools, run the CLI, or import the package) — request patterns, response shapes, and pointers into the gotchas.                                                                                                                                                                                                                                                                                                  |

More from zapier/connectors

SkillDescription
dropboxAgent-callable Dropbox tools — upload, organize, find, and share files and folders. Use when the user wants to manage Dropbox content (save, move, search, share, list, or read files), including requests that don't name Dropbox explicitly, e.g. "save this report to my cloud storage" or "share that folder with Sam".
google-contactsAgent-callable Google Contacts tools — create, find, update, and delete contacts, manage contact groups (labels) and membership, and read auto-saved other contacts. Use when the user mentions Google Contacts or wants to look up, save, or organize people — including requests that don't name Google Contacts explicitly, e.g. add Jane to my contacts, find Bob's email.
google-tasksAgent-callable Google Tasks tools — create, list, update, complete, move, and delete tasks and task lists. Use when the user wants to manage Google Tasks or to-dos, even if they don't name Google Tasks explicitly.
heygenAgent-callable HeyGen tools — generate AI avatar videos, translate and lip-sync videos, synthesize speech, and clone or browse voices and avatars. Use when the user mentions HeyGen or wants to create, translate, or check the status of AI videos, or to generate or clone a voice — including requests that don't name HeyGen, e.g. make an avatar video from a script, translate a video to Spanish, turn a script into a voiceover, or clone a voice from a recording.
microsoft-outlookAgent-callable Microsoft Outlook tools — read and search mail, send/reply/forward, organize messages and folders, manage calendar events, and manage contacts. Use when the user mentions Outlook, Microsoft 365 mail/calendar/contacts, or wants to send, read, search, or organize email, schedule events, or look up contacts — even if they don't name Outlook explicitly.
microsoft-sharepointAgent-callable Microsoft SharePoint tools — find sites and document libraries, browse, search, upload, move and share files, manage lists and list items, and author site pages. Use when the user mentions SharePoint or wants to work with SharePoint sites, files, folders, lists, or pages, even if they don't name SharePoint explicitly.
runwayAgent-callable Runway tools — generate images and video from text or images, edit and upscale media, animate characters, generate speech and sound effects, and run marketing recipes, plus track generation jobs. Use when the user mentions Runway or wants to generate, edit, or upscale AI media, even if they don't name Runway explicitly.