Reports
Run a report

Run a report via the API

Access Stripe's financial reports programmatically to automate your reconciliation workflow.

The financial reports in the dashboard provide downloadable reports in CSV format for a variety of accounting and reconciliation tasks. These reports are also available via the API, so that on a schedule of your choosing—or on an ad-hoc basis—you can automatically receive and ingest these report files into your internal accounting pipeline.

Report types

Each financial report in the dashboard provides several different CSV downloads. All of the available downloads for the following reports are also available via the API:

See the Report types reference for a complete list of available report types, including legacy versions and reports for Connect platforms.

Be aware that these CSV reports format monetary amounts in major currency units as a decimal number. For example, 10 USD is formatted as dollars-and-cents (10.00). This differs from the Stripe API, where you specify amounts in the currency’s minor unit (U.S. cents) as an integer. In the API, 10 USD would be formatted as 1000.

Data availability

Stripe prepares data for your reports on a daily basis, with each day’s data defined by activity that takes place between 12:00am UTC and 11:59pm UTC. Report options provides details on expected processing time and data availability for each report.

To programmatically determine the time range of data available for a given report type, retrieve the ReportType object of interest. For example, the Balance summary report has the ID balance.summary.1, so you can retrieve the object as follows:

Terminal
curl https://api.stripe.com/v1/reporting/report_types/balance.summary.1 \ -u
sk_test_4eC39HqLyjWDarjtT1zdp7dc
\ # Note that a live-mode API key is required.

In the example response below, the fields data_available_start and data_available_end reflect the full range of valid times for this report type. However, you’ll most often be running reports for a smaller interval within that range:

{ id: "balance.summary.1", name: "Balance summary", version: "1", object: "reporting.report_type", data_available_start: 1519862400, # 2018-03-01 00:00 data_available_end: 1517356800, # 2018-05-04 00:00 updated: 1517382720, # 2018-05-04 07:12 }

New data notifications

As soon as a report type has new data available, Stripe publishes a reporting.report_type.updated event with the updated ReportType object. To access these events, you must have a webhook configured that explicitly selects to receive reporting.report_type.updated events; webhooks that listen for ‘all events’ won’t receive them. After you receive such an event, you can then run the report. For details, see our recommended integration pattern.

Creating and accessing report runs

The ReportRun API object represents an instance of a ReportType generated with specific parameters. (Required and optional parameters for each report type are documented in the Reports types reference.) For example, you can create a Balance change from activity summary report for April 2018 as follows:

Terminal
curl https://api.stripe.com/v1/reporting/report_runs \ -u
sk_test_4eC39HqLyjWDarjtT1zdp7dc
\ -d report_type="balance_change_from_activity.itemized.3" \ -d "parameters[interval_start]"=1577865600 \ -d "parameters[interval_end]"=1580544000 \ -d "parameters[timezone]"="America/Los_Angeles" \ -d "parameters[columns][]"=created \ -d "parameters[columns][]"=reporting_category \ -d "parameters[columns][]"=net # Timestamps are for 2020-01-01 00:00 PST and 2020-02-01 00:00 PST. # The columns parameter is optional. A default set of columns will be provided if you don't specify a value. # Note that a live-mode API key is required.

When first created, the object appears with status="pending":

{ id: "frr_123", object: "reporting.report_run", livemode: true, report_type: "balance_change_from_activity.itemized.3", parameters: { columns: [ "created", "reporting_category", "net" ], interval_start: 1577865600, # 2020-01-01 00:00 PST interval_end: 1580544000, # 2020-02-01 00:00 PST timezone: "America/Los_Angeles", }, created: 1580832900, # 2020-02-04 08:15 PST status: "pending", result: nil, }

When the run completes, Stripe updates the object: it will have a status of succeeded, along with a nested result object, containing a URL that you can use to access the file with your API key. For example, if you were to retrieve the above report run after it completes, the response would be:

{ id: "frr_123", object: "reporting.report_run", livemode: true, report_type: "balance_change_from_activity.itemized.3", parameters: { columns: [ "created", "reporting_category", "net" ], interval_start: 1577865600, # 2020-01-01 00:00 PST interval_end: 1580544000, # 2020-02-01 00:00 PST timezone: "America/Los_Angeles", }, created: 1580832900, # 2020-02-04 08:15 PST status: "succeeded", succeeded_at: 1580832960, # 2020-02-04 08:16 PST result: { id: "file_xs8vrJzC", object: "file", url: "https://files.stripe.com/v1/files/file_xs8vrJzC/contents", created: 1580832960, # 2020-02-04 08:16 PST purpose: "report_run", size: 53075, type: "csv" }, }

To retrieve the file contents, use your API key to access the file specified by result.url:

Terminal
curl https://files.stripe.com/v1/files/file_xs8vrJzC/contents \ -u
sk_test_4eC39HqLyjWDarjtT1zdp7dc
\ # Note that a live-mode API key is required.

Notification of report run completion

Most runs complete within a few minutes. However, some runs could take longer—depending on the size of your total data set, and on the time range your report covers.

When a requested report run completes, Stripe sends one of two webhooks:

  • A reporting.report_run.succeeded webhook will be sent if the run completes successfully.
  • A reporting.report_run.failed webhook will be sent if the run fails. (This should be rare, but we recommend that integrations be prepared to handle this case in the same manner as catching a 500 response.)

In both cases, the webhook payload includes the updated ReportRun object, which includes status succeeded or failed, respectively.

Recommended integration pattern for automated reporting

Prerequisite: configure a webhook that explicitly selects to receive reporting.report_type.updated events; webhooks that listen for ‘all events’ won’t receive them.

  1. A reporting.report_type.updated webhook is sent as soon as a new day’s data is available for a given report type. The payload includes the updated ReportType object. You’ll typically receive 10–20 webhooks each day, one for each report type. (Different users are eligible for different reports.)
  2. Upon receiving the reporting.report_type.updated webhook for the desired report type and range of data availability, [create a report run]. The response will contain a new ReportRun object, initialized with status=pending.
  3. When the run completes, a reporting.report_run.succeeded webhook is sent. This webhook includes the nested field result.url. (As mentioned above, in the rare case of a failure, we’ll send a reporting.report_run.failed event instead.)
  4. Access the file contents at result.url, using your API key.