Google Analytics
Let hires run GA4 reports on your traffic, sources and conversions, and see who's on your site right now.
Explore 4 actions and their permissionsExact inputs, sign-in scopes, access limits and approval rules.
With Google Analytics (GA4), a hire can:
- list the properties it may report on,
- run a report: metrics such as users, sessions, conversions or revenue, by dimensions such as date, source, page, country or event, over a date range, optionally compared with another, with a filter and an order,
- run a realtime report: who's on your site or app in the last 30 minutes,
- look up the dimension and metric names a property has, your custom ones included.
Hires only read: Roster asks Google for read-only access, so nothing they do changes anything in Google Analytics.
1. Make an OAuth app in Google Cloud
- In Google Cloud, create a project (or use one), then APIs & Services → Library, and turn on the Google Analytics Data API and the Google Analytics Admin API.
- APIs & Services → OAuth consent screen: Internal for a Google Workspace organisation; External for a personal account (then publish it, or Google stops the sign-in after 7 days).
- Add the scope
…/auth/analytics.readonly. - Credentials → Create credentials → OAuth client ID → Web application. Add the redirect URI Roster shows on the connection.
2. Connect it in Roster
- Open Integrations → Tools → Add a tool, search for Google Analytics and choose it.
- Paste the OAuth client ID and secret.
- Click Connect and sign in with a Google account that can view your GA4 properties.
3. Give hires access
On the hire's Tools tab, click Give access on Google Analytics:
- Properties: GA4 property IDs (in Google Analytics, Admin → Property details), one per line. Any other property is refused. Leave it empty for every property the account can view.
What hires get back
A report returns at most 50 rows unless the hire asks for up to 200, with a note saying how many
there were in all, and whether Google sampled the data. Google Analytics keeps no personal data in
reports; if a site sent an email address as a page path or custom dimension, hires see [email].
If something goes wrong
- "Does not have sufficient permissions": the signed-in Google account can't view that property. Add it in Google Analytics under Admin → Property access management.
- "API has not been used in project": turn on both Analytics APIs in Google Cloud (step 1).
- "Exhausted property tokens": Google limits how much reporting each property can do per hour and per day; the hire tries again later or asks for a smaller report.
Tools and permissions reference
This reference is built from the same definitions Roster uses to connect Google Analytics and give hires access. It updates with each release.
Authentication and requested permissions
The account or app you connect sets the outer limit. Each hire's access can narrow it further. Connecting a tool gives it to no hire until you give access on that hire's Tools tab.
OAuth 2.0
From the OAuth client (Web application) you created in Google Cloud for Roster.
Requested scopes:
https://www.googleapis.com/auth/analytics.readonly
Connection fields
| Field | What to provide |
|---|---|
OAuth app client IDclientIdOptional | From the OAuth client (Web application) you created in Google Cloud for Roster. |
OAuth app client secretclientSecretOptional · sealed secret | Use the value for your account or connection. |
Per-hire limits
Read-only hires receive only actions that read. Read-and-write access also allows actions that change things, where the connection itself permits them. An empty resource allowlist usually means everything the connected account can reach; each field below explains its meaning.
| Field | What to provide |
|---|---|
PropertiespropertiesOptional | GA4 property IDs (Admin → Property details), one per line. Leave empty for every property the signed-in account can read. |
Actions
4 actions: 4 only read and 0 change something. A read action may still need approval when your workspace or hire is set to ask. A locked approval requirement always applies.
4 of 4 actions. Open an action for its arguments and full input schema.
list_propertiesRead only
The GA4 properties this hire may report on, with their accounts.
Approval: Uses your workspace and hire approval settings.
This action takes no arguments.
Full input schema (JSON)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {}
}run_reportRead only
A GA4 report: metrics (e.g. activeUsers, sessions, conversions, totalRevenue) by dimensions (e.g. date, sessionSource, pagePath, country, eventName) over a date range, optionally compared with a second one, with a filter on one dimension and an order. Dates are YYYY-MM-DD, today, yesterday or NdaysAgo.
Approval: Uses your workspace and hire approval settings.
| Argument | Type | Details |
|---|---|---|
propertyRequired | string | the GA4 property ID (a number) |
metricsRequired | string[] | See input schema below. |
dimensionsOptional | string[] | See input schema below.Default: [] |
startOptional | string | See input schema below.Default: "28daysAgo" |
endOptional | string | See input schema below.Default: "yesterday" |
compare_startOptional | string | a second range to compare with (with compare_end) |
compare_endOptional | string | See input schema below. |
filterOptional | object | See input schema below. |
order_byOptional | string | a metric or dimension to sort by (metrics highest first) |
limitOptional | integer | See input schema below.Default: 50 |
Full input schema (JSON)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"property": {
"description": "the GA4 property ID (a number)",
"type": "string"
},
"metrics": {
"minItems": 1,
"maxItems": 10,
"type": "array",
"items": {
"type": "string",
"pattern": "^[A-Za-z][A-Za-z0-9_]*(:[A-Za-z0-9_]+)?$"
}
},
"dimensions": {
"default": [],
"maxItems": 5,
"type": "array",
"items": {
"type": "string",
"pattern": "^[A-Za-z][A-Za-z0-9_]*(:[A-Za-z0-9_]+)?$"
}
},
"start": {
"default": "28daysAgo",
"type": "string",
"pattern": "^(\\d{4}-\\d{2}-\\d{2}|today|yesterday|\\d{1,4}daysAgo)$"
},
"end": {
"default": "yesterday",
"type": "string",
"pattern": "^(\\d{4}-\\d{2}-\\d{2}|today|yesterday|\\d{1,4}daysAgo)$"
},
"compare_start": {
"description": "a second range to compare with (with compare_end)",
"type": "string",
"pattern": "^(\\d{4}-\\d{2}-\\d{2}|today|yesterday|\\d{1,4}daysAgo)$"
},
"compare_end": {
"type": "string",
"pattern": "^(\\d{4}-\\d{2}-\\d{2}|today|yesterday|\\d{1,4}daysAgo)$"
},
"filter": {
"type": "object",
"properties": {
"dimension": {
"type": "string",
"pattern": "^[A-Za-z][A-Za-z0-9_]*(:[A-Za-z0-9_]+)?$"
},
"match": {
"default": "exact",
"type": "string",
"enum": [
"exact",
"contains",
"begins_with",
"ends_with",
"regex"
]
},
"value": {
"type": "string",
"minLength": 1,
"maxLength": 500
},
"exclude": {
"default": false,
"type": "boolean"
}
},
"required": [
"dimension",
"value"
]
},
"order_by": {
"description": "a metric or dimension to sort by (metrics highest first)",
"type": "string",
"pattern": "^[A-Za-z][A-Za-z0-9_]*(:[A-Za-z0-9_]+)?$"
},
"limit": {
"default": 50,
"type": "integer",
"minimum": 1,
"maximum": 200
}
},
"required": [
"property",
"metrics"
]
}realtime_reportRead only
Who's on the site or app right now: metrics (activeUsers, eventCount, conversions) by realtime dimensions (country, unifiedScreenName, eventName, platform) over the last minutes.
Approval: Uses your workspace and hire approval settings.
| Argument | Type | Details |
|---|---|---|
propertyRequired | string | the GA4 property ID (a number) |
metricsOptional | string[] | See input schema below.Default: ["activeUsers"] |
dimensionsOptional | string[] | See input schema below.Default: [] |
minutesOptional | integer | the last N minutes (30 at most on standard properties)Default: 30 |
limitOptional | integer | See input schema below.Default: 25 |
Full input schema (JSON)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"property": {
"description": "the GA4 property ID (a number)",
"type": "string"
},
"metrics": {
"default": [
"activeUsers"
],
"minItems": 1,
"maxItems": 5,
"type": "array",
"items": {
"type": "string",
"pattern": "^[A-Za-z][A-Za-z0-9_]*(:[A-Za-z0-9_]+)?$"
}
},
"dimensions": {
"default": [],
"maxItems": 3,
"type": "array",
"items": {
"type": "string",
"pattern": "^[A-Za-z][A-Za-z0-9_]*(:[A-Za-z0-9_]+)?$"
}
},
"minutes": {
"default": 30,
"description": "the last N minutes (30 at most on standard properties)",
"type": "integer",
"minimum": 1,
"maximum": 60
},
"limit": {
"default": 25,
"type": "integer",
"minimum": 1,
"maximum": 100
}
},
"required": [
"property"
]
}list_fieldsRead only
The dimension and metric names a property's reports take, its custom ones included, by words.
Approval: Uses your workspace and hire approval settings.
| Argument | Type | Details |
|---|---|---|
propertyRequired | string | the GA4 property ID (a number) |
searchOptional | string | See input schema below. |
Full input schema (JSON)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"property": {
"description": "the GA4 property ID (a number)",
"type": "string"
},
"search": {
"type": "string",
"maxLength": 100
}
},
"required": [
"property"
]
}Watches and incoming events
- No built-in watch is declared. Give a hire a scheduled responsibility if it should check this service regularly.
- No incoming webhook handler is declared for this integration.
Limits and troubleshooting
- Permission errors: check both the connected account's rights and the hire's resource and read/write limits.
- Expired or revoked access: reconnect or replace the key on the connection.
- Rate limits and unavailable services can interrupt work. The hire's timecard records the outcome.
- The action schema describes accepted inputs. It does not grant additional access or bypass approvals.