FunnelHound / Guides / App Store Connect to Google Sheets
App Store Connect to Google Sheets: three routes, from five minutes to fully automatic
There is no "connect to Google Sheets" button in App Store Connect, and no Sheets formula can log in for you. Three routes exist: paste the export files by hand, run a small scheduled script that calls the App Store Connect API and appends rows, or pay a connector to do the second thing for you. The first takes five minutes per refresh, the second takes an evening to build and then nothing, the third takes a credit card.
Route 1: paste the export, five minutes
- App Store Connect → Analytics → Metrics. Pick a metric, set the date range, use the export control on the chart to download a CSV. Repeat per metric. The complete menu of export controls is in how to export App Store Connect analytics.
- For money, Sales and Trends → Reports → download the daily or monthly TSV.
- In Sheets, File → Import → Upload, choose "Append to current sheet", separator auto-detect. The Analytics CSV has a header row; the sales TSV has one too, tab separated.
Good for a one-off question or a monthly board slide. Falls apart the third time you do it, and every repeat is a chance to paste the wrong date range on top of the right one.
Route 2: a scheduled script, one evening
The building blocks: an App Store Connect API key (Issuer ID, Key ID, .p8), a Google service account with edit rights on the sheet, and anywhere that runs a script on a timer. GitHub Actions on a cron is free and needs no server. The loop looks like this:
- Sign the token. PyJWT with the ES256 algorithm, iss = Issuer ID, kid = Key ID, aud = appstoreconnect-v1, 20-minute expiry. The working code is in the Python walkthrough.
- Sales: GET /v1/salesReports for yesterday, DAILY, SUMMARY, SALES, with your vendor number. Gunzip, split on tabs, keep SKU, units, proceeds, country.
- Analytics: one ONGOING analyticsReportRequests per app, created once; each morning list the latest DAILY instance of "App Store Discovery and Engagement" and "App Store Downloads", download the segments, sum impressions, page views and downloads per app.
- Append: spreadsheets.values.append with one row per app per day. The gspread library turns that into one call.
- Lag: Apple's analytics run two to three days behind, sales about one. Fetch "today minus three" for analytics and accept that the latest rows fill in late. Re-running the same date must overwrite, not duplicate.
The Apps Script catch
The obvious plan, a Google Apps Script bound to the sheet with a time-driven trigger, hits a wall at step two. Apple's token must be signed with ES256, an elliptic-curve signature, and Apps Script's Utilities class ships HMAC and RSA helpers only. Two workarounds exist: paste a JavaScript crypto library such as jsrsasign into the script project and sign with it, or stand up a tiny external function that signs tokens and let the script call that. Both work; both are more moving parts than a Python file on a cron, which is why route 2 above is not written in Apps Script.
Route 3: connectors
Warehouse and spreadsheet connectors, from the Airbyte and Fivetran family down to the Sheets add-on marketplace, all offer an App Store Connect source. You paste the same three credentials plus the vendor number, pick tables, set a schedule. Pricing ranges from free tiers with row limits to real money per month. Right for a team that already runs one of these tools; the wrong size for one developer with three apps, who ends up paying rent on eighty lines of Python.
A sheet layout that survives
| date | app | impressions | page_views | downloads | deletions | units | proceeds_usd |
|---|---|---|---|---|---|---|---|
| 2026-10-30 | FunnelHound | 1,204 | 118 | 41 | 9 | 6 | 21.10 |
| 2026-10-30 | Second app | 530 | 44 | 12 | 3 | 0 | 0.00 |
- Long format, one row per app per day. Adding an app adds rows, not columns, so formulas and pivots keep working.
- Raw numbers only in the data tab. Rates (page views ÷ impressions, downloads ÷ page views, deletions ÷ downloads) live in a second tab or a pivot. Storing a rate loses the ability to re-aggregate by week.
- ISO dates as text or real dates, never both. Half the broken sheets are a date column that is half strings.
- A milestones tab with date and note. The whole point of the sheet is reading a change against the number that followed it.
Or skip the sheet
Most people building this sheet want three things from it: the funnel per app, the trend after each release, and a glance without logging in. FunnelHound exists because that sheet kept breaking. It signs the same ES256 token on your iPhone, pulls the same analytics and sales reports, and draws impressions through purchases with milestones on the chart. The sheet remains the right tool when the question is "join my ad spend to my installs", which is a spreadsheet question and always will be.
The sheet, minus the sheet
Funnel per app, deletions beside installs, and a before-and-after for every milestone, straight from the App Store Connect API to your iPhone. Keep Sheets for the ad spend joins.
Get FunnelHoundData notes: endpoint names, report categories and the ONE_TIME_SNAPSHOT and ONGOING access types follow Apple's App Store Connect API documentation as of 2026. Apps Script's Utilities class documents HMAC and RSA signature helpers and no ECDSA; verify against Google's current reference before building on it. Daily sales report retention is roughly one year; Apple does not publish an exact figure. Sample rows are illustrative.