Google Analytics 4 Exporter: GA4 Reports to CSV, Excel & JSON avatar

Google Analytics 4 Exporter: GA4 Reports to CSV, Excel & JSON

Pricing

from $0.40 / 1,000 report rows

Go to Apify Store
Google Analytics 4 Exporter: GA4 Reports to CSV, Excel & JSON

Google Analytics 4 Exporter: GA4 Reports to CSV, Excel & JSON

Export Google Analytics 4 reports from your own GA4 properties with Google's official Data API: traffic, channels, landing pages, pages, events, ecommerce, realtime or any custom report. Many properties per run, period comparisons, flat rows. $0.50 per 1,000 rows plus a small start fee.

Pricing

from $0.40 / 1,000 report rows

Rating

0.0

(0)

Developer

Aaron Tuttle

Aaron Tuttle

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

7 days ago

Last modified

Share

Export Google Analytics 4 reports for $0.50 per 1,000 rows: traffic by day, channels, landing pages, events, ecommerce, realtime or any custom report, from one or many GA4 properties in one run, as flat rows ready for Google Sheets, Excel, Looker Studio, BigQuery or your AI agent.

It uses Google's official GA4 Data API with your own Google service account, so it reads only the properties you give it access to. No scraping, no browser, no proxies, and no personal data: GA4 reports are aggregated counts, and Google hides small groups of users itself.

What GA4 data can you export?

Pick any of 15 ready-made reports, or build your own from any GA4 dimensions and metrics (including your custom dimensions such as customEvent:plan_type).

ReportOne row perMain columns
Traffic overview by daydayactive users, new users, sessions, engaged sessions, engagement rate, avg. session duration, views, events, key events, revenue
Traffic by channelchannel (Organic Search, Paid Search, Social …)sessions, users, engagement, key events, key event rate, revenue
Source / mediumsource + mediumsame as channels
Campaigns (UTM)campaign + source + mediumsame as channels
Landing pageslanding page with query stringsessions, users, engagement and bounce rate, key events, revenue
Pages and screenspage path + titleviews, users, views per user, engagement time, events, key events
Eventsevent nameevent count, users, events per user, key events, event value
Key events (conversions) by channelkey event + channelkey events, users, revenue
Devicesdevice + operating system + browserusers, sessions, engagement, key events, revenue
Countries / Citiescountry (and region, city)users, sessions, engagement, key events, revenue
New vs returningnew / returningusers, sessions, engagement, key events, revenue
Ecommerce: productsproduct name + IDitems viewed, added to cart, purchased, item revenue
Ecommerce: revenue by daydaypurchases, purchase revenue, total revenue, avg. purchase, purchasers, first-time purchasers
Realtimecountry + device + screen, last 30 minutesactive users, views, events, key events

What makes this exporter different

  • Many properties per run. List property IDs, or leave the list empty to export every property your service account can read. Ideal for agencies.
  • Period comparisons built in. Add sessionsPrevious and sessionsChangePct (and the same for every metric) next to each row, against the previous period or the same dates last year.
  • Split any report by day, week or month for time series (e.g. channels per day).
  • Simple filters like country==United States, pagePath=@/blog or sessions>100.
  • Friendly errors. Typos get suggestions ("did you mean sessions?"), and missing access or a turned-off API tells you exactly what to click.
  • Totals, sampling and quota for every report are in the run summary.

How much does it cost to export GA4 data?

You pay per report row delivered, plus a small start fee. There are no platform fees: compute is included.

Free planStarterScaleBusiness
Per 1,000 report rows$0.60$0.50$0.45$0.40
Run start$0.002$0.002$0.002$0.002
  • The default run (3 reports, last 28 days, one property) is usually 50–300 rows: about $0.03–$0.15.
  • Apify's $5 free plan ≈ 8,300 report rows.
  • Reports that fail, rows over your limits, and runs without credentials cost nothing beyond the start fee. (If a long report fails halfway, you pay only for the rows already delivered.) Set Maximum cost per run in Apify and the run stops cleanly at that amount.
  • Google doesn't charge for the GA4 Data API; it only limits how much each property can request per day (about 200,000 "tokens", far more than daily exports need).

How to connect your GA4 property (5 minutes, once)

  1. Turn on the API. In Google Cloud Console pick or create a project, search for Google Analytics Data API and click Enable. Also enable Google Analytics Admin API if you want property names, local time zones, or "export all my properties".
  2. Create a service account. Go to IAM & Admin → Service accounts → Create service account, give it a name (e.g. ga4-reader) and click Done. You don't need to give it any Cloud roles.
  3. Download its key. Open the service account → Keys → Add key → Create new key → JSON. A .json file downloads.
  4. Give it access in Google Analytics. In GA4 open Admin → Property access management → + → Add users, paste the service account e-mail (it ends in iam.gserviceaccount.com), choose Viewer, and click Add. Repeat for each property, or add it once at account level.
  5. Run. Paste the whole .json file into Service account key (JSON), enter your property ID (Admin → Property details, a number like 123456789), and click Start.

The key is stored by Apify as an encrypted secret input, used only to sign in to Google, and never logged or written to the results. To revoke access at any time, delete the key in Google Cloud or remove the user in Google Analytics.

If your organisation blocks service account keys, use Sign in with OAuth instead: an OAuth client ID, client secret and a refresh token with the analytics.readonly scope.

How to export GA4 reports

Input example: last month's channels and landing pages for two properties, compared with the previous month:

{
"serviceAccountKey": "{ \"type\": \"service_account\", … }",
"propertyIds": ["123456789", "987654321"],
"reports": ["channels", "landingPages"],
"dateRange": "lastMonth",
"comparison": "previousPeriod",
"filters": ["country==United States|Canada"]
}

Output example (one row of the channels report):

{
"propertyId": "123456789",
"propertyName": "Example shop",
"report": "channels",
"startDate": "2026-09-01",
"endDate": "2026-09-30",
"previousStartDate": "2026-08-02",
"previousEndDate": "2026-08-31",
"currency": "USD",
"sessionDefaultChannelGroup": "Organic Search",
"sessions": 18420,
"activeUsers": 14211,
"newUsers": 11037,
"engagedSessions": 12102,
"engagementRate": 0.657004,
"averageSessionDuration": 142.318,
"keyEvents": 512,
"sessionKeyEventRate": 0.027796,
"totalRevenue": 23110.5,
"sessionsPrevious": 16890,
"sessionsChangePct": 9.1
}

The values above are illustrative. Column names are GA4's own API names, so they match Google's documentation and Looker Studio. Dates are YYYY-MM-DD (weeks 2026-W40, months 2026-10); rates are fractions (0.657 = 65.7%); durations are seconds.

Custom report: any combination of up to 9 dimensions and 10 metrics. Fill in Custom report: metrics and dimensions, or pass several in More custom reports (JSON):

[
{ "name": "blog", "dimensions": ["pagePath", "sessionSource"], "metrics": ["screenPageViews", "userEngagementDuration"], "filters": ["pagePath=^/blog"], "orderBy": "-screenPageViews", "limit": 500 },
{ "name": "live", "realtime": true, "dimensions": ["unifiedScreenName"], "metrics": ["activeUsers"] }
]

Filters (one per line, all must match; text ignores case; a filter is skipped, with a note in the log, for reports it can't apply to, e.g. sessions>100 on the products report or most fields on realtime): == equals (country==Germany|France for several values), != not equal, =@ contains, !@ doesn't contain, =^ starts with, =$ ends with, =~ regex, !~ not regex, and >, >=, <, <= for metrics (sessions>100).

Run summary: the OUTPUT record in the key-value store lists every report with its row count, how many rows GA4 had, totals (and previous-period totals), notes about sampling or thresholds, the remaining property quota, and any error.

Google Analytics 4 API: Python, JavaScript, Zapier, Make and AI agents (MCP)

Run it from your code with the Apify API (Python or JavaScript client), on a schedule (e.g. every Monday, exported to Google Sheets with Apify's integration), or from Zapier, Make and n8n.

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("aaronoptimus/google-analytics-4-exporter").call(run_input={
"serviceAccountKey": open("ga4-key.json").read(),
"propertyIds": ["123456789"],
"reports": ["trafficOverview", "channels"],
"dateRange": "last7Days",
})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
print(row["report"], row.get("date") or row.get("sessionDefaultChannelGroup"), row["sessions"])

AI agents (Claude, Cursor, ChatGPT and others that support MCP) can call it through Apify's MCP server: https://mcp.apify.com?tools=aaronoptimus/google-analytics-4-exporter.

What this tool doesn't do

  • It doesn't read GA4 properties you can't access. Every property needs your service account (or OAuth user) added in Google Analytics.
  • No Universal Analytics (UA- IDs). Google shut it down in 2024.
  • No user-level or personal data. GA4 reports are aggregated, and Google applies its own privacy thresholds (noted in the run summary when it does).
  • No raw event export. For event-level data, use GA4's free BigQuery export.

FAQ

Do I need a Google Cloud bill or credit card? No. The GA4 Data API is free, and creating a service account doesn't need billing.

Why does my report have fewer rows than the GA4 interface? GA4 hides rows with only zeros (turn on Keep rows where every metric is 0), applies privacy thresholds to small groups, and the tool stops at Max rows per report (10,000 by default).

Which time zone are the dates in? Each property's own time zone (read with the Admin API). Without the Admin API, dates are counted in UTC and the log says so.

What if I get "has no access to property"? Add the e-mail shown in the message as a Viewer under Admin → Property access management, and check that you used the numeric property ID (not the G- measurement ID).

Can I export many properties at once? Yes. List them, or leave the list empty to export every property the service account can read.

Found a problem or need a field? Open an issue on the Issues tab. If the Actor saves you time, a short review helps others find it.

This Actor is an independent tool and is not affiliated with, endorsed by or sponsored by Google. Google Analytics is a trademark of Google LLC.