Google Analytics Data API (GA4): The Access Path That Decides Your Timeline
A client wants their GA4 numbers inside your dashboard. Straightforward, until you hit a fork most integration guides skip entirely — and the choice you make at that fork decides whether you ship this week or wait on a Google review first.
The technical call (runReport, property IDs, dimensions and metrics) is the easy part. The part that actually decides your launch date is which access model your product falls under, and whether GA4’s quota system is designed the way most builders assume it is.
Two Access Paths, Two Different Timelines
Google documents an explicit exception for apps that only touch data they already own. The moment a client’s own Google Account enters the picture, that exception disappears.
Service Account — Your Own Property
If the app only ever reads GA4 data from properties you own or manage directly, a Google Cloud service account granted access inside the property’s own Analytics settings works with no OAuth consent screen and no Google review. Google’s own verification documentation carves this out explicitly: apps that use a service account to access only their own data, without touching any user data tied to a Google Account, do not need to submit for verification.
OAuth — On Behalf of Clients
The moment your app asks a client to sign in with their own Google Account so you can read their property, you are requesting the analytics.readonly scope on their behalf. Google classifies this as a sensitive scope, and its own documentation states plainly that the review process “can take up to 10 days to complete” — on top of branding checks, a demonstration video, and a published privacy policy before the flow can leave testing mode.
Where the Setup Actually Goes
Decide the access model first
This single decision determines whether Cloud Console setup takes an afternoon or opens a multi-week review runway — it has to be made before any integration code gets written, not after a client demo is already promised.
Enable the Data API and match credentials to the model
A service account key for properties you own, or an OAuth client plus a consent screen for properties a client owns. Enabling the API in Cloud Console is a separate step from actually being allowed to read a specific property.
Property access still has to be granted manually
Whichever credential type is used, the property owner has to add that account or app inside the GA4 property’s own access-management settings before any report request returns data. Cloud Console access and property-level access are two separate grants.
If sensitive scopes are involved, prepare the verification package
Branding information, verified domain ownership, an accurate privacy policy link, and a screen recording that shows the consent flow and the actual feature the scope powers — assembled before submission, not scrambled together after a rejection.
Design report calls around the quota architecture from day one
GA4’s quota system has more moving parts than a single daily ceiling, and finding that out after a multi-client dashboard is already live under load is the expensive way to learn it.
The Quota System, In Numbers
Google’s own Data API limits documentation splits every property into three independently tracked quota categories — Core (standard reports), Realtime, and Funnel — each with its own ceiling, and each request only ever draws from one of them.
| Layer | Standard property | Analytics 360 property |
|---|---|---|
| Tokens per property per hour | 40,000 | 400,000 |
| Tokens per project, per property, per hour | 14,000 | 140,000 |
| Server-error requests per project, per property, per hour | 10 | 50 |
Daily quotas reset at midnight Pacific Time. Hourly quotas reset within the hour, but not necessarily on the clock hour boundary.
Where Multi-Client Dashboards Quietly Break
The property quota looks fine. The project quota doesn’t.
Every request draws against two ceilings at once: the property’s overall hourly quota, and a separate, smaller per-project-per-property hourly quota. Once more than roughly three separate projects are calling the same property inside the same hour, the smaller per-project ceiling runs out first — while the property’s own overall quota still shows room.
Token cost isn’t known until the request runs
Most calls cost 10 tokens or fewer, but Google’s own documentation states the exact cost of a request is determined at execution time based on its complexity — row count, dimension and metric combinations, date range, and data cardinality. A single dense report on a high-traffic property can consume far more of the hourly budget than a lighter call, with no reliable way to know the exact number in advance.
Server-error quota is a separate lockout, not a slowdown
Failed requests draw against their own server-error quota, tracked per project, per property, per hour. Once that specific quota is exhausted, every request from that project to that property gets blocked — a different failure mode from ordinary throttling, and one that keeps blocking requests even after the main token quota has plenty left.
Realtime widgets don’t borrow from the main report’s budget — or add extra room
Realtime and Funnel report types are tracked completely separately from Core, with identical numeric ceilings. A Realtime panel on a dashboard doesn’t compete with the main GA4 report for tokens, but assuming it has extra headroom beyond its own matching limit is a common miscalculation.
Picking the wrong access model for a GA4 integration — OAuth when a service account would have covered it, or the reverse — either adds an unnecessary verification runway or blocks the multi-client use case the product actually needs. Getting that decision right before Cloud Console setup starts, and structuring report calls around the real quota layers rather than the headline daily number, is the difference between a dashboard that ships and one that stalls mid-review. For a closer look at what a Google API access gate at this level actually requires, see Google API Verification Service and the related walkthrough on Google Business Profile API access.