All posts
AUTOMATION

App Store Connect Reports API: automating your subscription metrics pipeline in 2026

The Reports API delivers raw daily subscription data — active counts, events, proceeds — that you can pipe into any analytics stack. Here is how to authenticate, which report types matter for subscription apps, and how to build a lightweight automated pipeline.

By the AppsOps team · · 7 min read

Most App Store Connect discussions focus on the REST API — the endpoint set that lets you update prices, manage metadata, and push promotional offers. But there is a second, quieter API sitting underneath it that subscription developers often ignore until they outgrow the ASC dashboard: the Reports API. It delivers the same raw data that powers Apple's Sales and Trends reports, but as downloadable files you can pull on a schedule, parse programmatically, and pipe into any analytics stack you already run.

This guide covers what the Reports API exposes, how authentication works, the specific report types relevant to subscription apps, and how to build a lightweight automated pipeline from those raw files to the metrics that matter: MRR, renewal rates, and subscriber cohort counts.

Scope note: This post focuses on the App Store Connect Reports API — the /v1/salesReports, /v1/subscriptionReports, and /v1/financeSummaryReports endpoints. It does not cover the Server API (transaction verification) or the App Store Connect REST API for metadata and pricing, which are discussed in the complete 2026 API automation guide and the JWT authentication walkthrough.

What the Reports API actually gives you

When you download a report from ASC manually, you are essentially calling the Reports API through a browser. The programmatic version exposes the same data without human interaction, which unlocks a few genuinely useful patterns:

5 core report types relevant to subscription apps

The data arrives as gzip-compressed, tab-separated text files. Each column is documented in Apple's developer reference. The format is unglamorous but reliable — TSV is easy to parse in any language, load into a database, or pipe through standard shell tools.

Authentication: same key, same JWT, different endpoint

The Reports API uses identical authentication to the rest of the App Store Connect API: an Issuer ID, a Key ID, and a private key file (.p8) that you generate once in App Store Connect under Users and Access → Integrations → App Store Connect API. If you have already set up an API key for price automation, you can reuse the same key for Reports — no additional setup is required.

The only noteworthy restriction is role scope: your API key must have at minimum the Finance role to access financial reports, and the Sales role (or higher) to access sales and subscription reports. A key scoped to only Developer will be rejected at the Reports endpoints. If you encounter a 403, check the role assigned to your key, not just whether the key is valid.

JWT generation follows the same RS256 + 20-minute expiry pattern as every other App Store Connect API call. The JWT authentication walkthrough covers the mechanics in detail. For the Reports API specifically, the audience claim should remain appstoreconnect-v1.

A minimal shell one-liner to fetch a daily Sales report for yesterday looks like this (assuming $JWT is already exported):

curl -sS \
  "https://api.appstoreconnect.apple.com/v1/salesReports?filter[frequency]=DAILY&filter[reportDate]=2026-08-04&filter[reportType]=SALES&filter[vendorNumber]=YOUR_VENDOR_NO" \
  -H "Authorization: Bearer $JWT" \
  --compressed -o sales_2026-08-04.tsv

Subscription report types in detail

The table below maps the four report types most useful for subscription developers to their key columns and typical use cases. "Frequency" refers to the finest granularity Apple provides for that report type.

Report type Filter value Finest frequency Key columns Primary use case
Sales and Trends SALES Daily Units, Proceeds, Product Type Identifier, Country Code Revenue reconciliation, territory breakdown
Subscription SUBSCRIPTION Daily Active Free Trial Introductory Offers, Active Pay as You Go, Active Pay Up Front, Active Standard Price Subscriptions, Grace Period, Active Subscribers, Cancellations, Billing Retry Subscriber counts, intro offer conversion, grace period monitoring
Subscription Event SUBSCRIPTION_EVENT Daily Event, Subscription Apple ID, Product Type, Days Before Cancelling, Country Funnel reconstruction, churn attribution, win-back targeting
Subscriber SUBSCRIBER Daily Subscriber ID, Subscription Name, Event Date, Country, State, Subscriber Since Cohort analysis, territory-level retention curves

The SUBSCRIPTION and SUBSCRIPTION_EVENT reports are available on a daily frequency with up to a 13-month lookback. The SUBSCRIBER report is also daily. Financial reports are available monthly. All are gzip-compressed by default — the --compressed flag in curl handles decompression transparently.

Building a lightweight metrics pipeline

A fully automated pipeline does not require a data warehouse or a sophisticated ETL tool. For a solo developer or small team, a combination of a scheduled shell script, a SQLite database, and a simple dashboard (even a spreadsheet) is enough to surface the metrics that matter.

Here is a pattern that works well in practice:

  1. Fetch yesterday's reports. A cron job (or a CI schedule) generates a fresh JWT, calls the four endpoints above, and stores the resulting TSV files with date-stamped filenames.
  2. Load into SQLite. A short Python script reads each TSV and upserts rows into a local database. SQLite handles concurrency fine for read-heavy workloads at subscription-app scale.
  3. Compute metrics. Active subscribers, renewal rate (renewals / (renewals + cancellations) on a rolling 30-day window), MRR (active standard price subscribers × monthly price), and trial-to-paid conversion rate are all derivable from the SUBSCRIPTION and SUBSCRIPTION_EVENT tables.
  4. Alert on anomalies. A simple threshold check — if active subscribers drops more than 5% day-over-day, send a Slack webhook — catches billing outages and store disruptions before they compound.

Watch the 48-hour lag. Apple typically makes subscription reports available with a two-day delay. If today is August 5, the most recent available daily report is usually August 3. Build this lag into your pipeline — fetching reportDate=yesterday will return a 404 until the file is ready, which can mislead naive retry logic into treating a lag as an auth failure. A clean approach: always request date - 2 days and accept that your dashboard will show data up to 48 hours old.

What the Reports API cannot tell you

The Reports API gives you counts and proceeds, but it is not a replacement for a full analytics SDK or a server-side event log. Some gaps to be aware of:

For a subscription app operating across multiple territories, combining the Reports API data (for proceeds by country) with purchasing power parity data (for contextualizing price-to-ARPU ratios) gives a clearer picture than either source alone. The Territories section of AppsOps overlays App Store tier data with PPP indices for this reason.

13 months of daily subscription history available via the API

Practical tips and common mistakes

Use the correct vendor number. Your vendor number is visible in ASC under Payments and Financial Reports → View Financial Reports. It is a different identifier from your App ID or your Team ID. Using the wrong one returns a 404 that looks like a permissions error.

Handle the GZIP correctly. The API always returns compressed data regardless of whether you set an Accept-Encoding header. If you see garbled binary output, add --compressed to curl or decompress the bytes before parsing.

Paginate for large date ranges. Subscription Event reports for popular apps can have hundreds of thousands of rows per day. If you are backfilling historical data, fetch one day at a time rather than a wide date range to avoid timeouts and memory issues.

Store raw files before parsing. Retain the raw TSV files alongside your database. Apple occasionally revises historical reports (for example, after a dispute resolution changes a subscriber's status retroactively). Having the raw files lets you re-import without re-fetching.

Cross-reference with Financial reports for reconciliation. The Sales report and Financial report can differ slightly because Sales data uses estimated exchange rates at time of transaction while Financial data uses actual settlement rates. For revenue recognition purposes, financial proceeds are authoritative; for trend analysis, the Sales report's speed of availability makes it more useful.

Research from organizations like RevenueCat and Adapty suggests that teams who build even a minimal automated reporting pipeline catch subscriber anomalies — billing retries spiking, trial conversions dropping — days earlier than teams relying solely on the ASC dashboard's built-in alerts. The pipeline does not need to be sophisticated; the value is in the daily habit of looking at the numbers before they accumulate into a problem.

If you are considering whether to build this yourself or use a subscription management SDK that provides its own analytics layer, the 2026 SDK comparison covers the trade-offs in detail. For most apps below a few thousand active subscribers, the native Reports API plus a small Python script is enough. At scale, a dedicated SDK's pre-built dashboards become harder to replicate cheaply.

Sources and further reading

Share this post

Ready to put this into practice?

AppsOps is the first App Store ops dashboardPPP-fair pricing for 175 App Store territories, AI metadata localization in 39 languages, AI screenshot localization for 14 Apple device classes, and one-click App Store Connect API push — all from one dashboard, all for $19/month.

Try AppsOps free — no card →

Related reading