# Run a report from the Reports v1 API

Generate and download financial reports with the Reports v1 API.

Use this guide to generate and download financial reports for an existing Reports v1 API integration.

> #### Use the Reports v2 API for new integrations
> 
> For new integrations, use the [Reports v2 API](https://docs.stripe.com/data/api/reports.md) (`/v2/data/reports` and `/v2/data/report_runs`). Its larger report catalog includes curated SQL templates for common business questions and can show the SQL behind a financial report. You can also [read result rows in the API response](https://docs.stripe.com/data/api/reports.md#retrieve-report-run) instead of downloading a file and use [Stripe Organizations](https://docs.stripe.com/data/api/reports.md#organization-api-key).

## Before you begin

To run the reports in this guide:

- Use a live-mode [API key](https://docs.stripe.com/keys.md).
- When using a restricted API key, grant the `report_runs_and_report_types_read` permission to create report runs and retrieve report types and runs. See the [permissions reference](https://docs.stripe.com/keys/permissions-reference.md) for endpoint-specific permissions.
- Follow the [best practices for managing secret keys](https://docs.stripe.com/keys-best-practices.md), and store your key in an environment variable or secrets manager.

## Data availability 

Stripe prepares data for your reports twice a day. [Report options](https://docs.stripe.com/reports/options.md#data-availability) 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](https://docs.stripe.com/api/reporting/report_type/retrieve.md) 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:

```curl
curl https://api.stripe.com/v1/reporting/report_types/balance.summary.1 \
  -u "<<YOUR_SECRET_KEY>>:"
```

In the example response, the properties `data_available_start` and `data_available_end` reflect the full range of valid times for this report type. However, you typically run reports for a smaller interval within that range:

```json
{
  "id": "balance.summary.1",
  "name": "Balance summary",
  "version": "1",
  "object": "reporting.report_type",
  "data_available_start": 1517356800,
  "data_available_end": 1519862400,
  "updated": 1519862400
}
```

Timestamps, such as `data_available_start`, represent seconds since the Unix epoch. For example, `1519862400` represents the timestamp `2018-03-01 00:00 UTC`.

### New data notifications 

Stripe publishes `reporting.report_type.updated` events with the updated `ReportType` object twice per day (at 00:00 and 12:00 UTC). To access these events, you must have a [webhook configured](https://docs.stripe.com/webhooks.md#register-webhook) that explicitly receives `reporting.report_type.updated` events. Webhooks that listen for all events don’t receive them. [Verify incoming webhook signatures](https://docs.stripe.com/webhooks.md#verify-events) before processing events.

Because report data can update more frequently than the webhook events are sent, the `data_available_end` value on the `ReportType` might be later than the value in your most recent event payload. To check for the latest available data between webhook notifications, perform a GET request on the report type.

To reduce webhook traffic, Stripe doesn’t send these events to [Connect webhook endpoints](https://docs.stripe.com/connect/webhooks.md). After you receive the event, you can run the report. For details, see the [recommended integration pattern](https://docs.stripe.com/reports/v1-api.md#integration-pattern).

## Create and access report runs 

The `ReportRun` API object represents an instance of a `ReportType` generated with specific parameters. Review the documentation for the [report type](https://docs.stripe.com/reports/api.md#report-types) for the list of required and optional parameters for that type. For example, you can [create](https://docs.stripe.com/api/reporting/report_run/create.md) a **Balance change from activity itemized** report for January 2020 as follows:

```curl
curl https://api.stripe.com/v1/reporting/report_runs \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d "report_type=balance_change_from_activity.itemized.3" \
  -d "parameters[interval_start]=1577865600" \
  -d "parameters[interval_end]=1580544000" \
  --data-urlencode "parameters[timezone]=America/Los_Angeles" \
  -d "parameters[columns][]=created" \
  -d "parameters[columns][]=reporting_category" \
  -d "parameters[columns][]=net"
```

The timestamps represent January 1, 2020 at 00:00 PST and February 1, 2020 at 00:00 PST. The `columns` parameter is optional. If you omit it, the report returns a default set of columns.

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

```json
{
  "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,
    "interval_end": 1580544000,
    "timezone": "America/Los_Angeles"
  },
  "created": 1580832900,
  "status": "pending",
  "result": null
}
```

When the run completes, Stripe updates the object, and it has a `status` of `succeeded`. It also has a nested `result` object, containing a URL that you can use to access the file with your API key. For example, if you [retrieve](https://docs.stripe.com/api/reporting/report_run/retrieve.md) the report run after it completes, the response is:

```json
{
  "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,
    "interval_end": 1580544000,
    "timezone": "America/Los_Angeles"
  },
  "created": 1580832900,
  "status": "succeeded",
  "succeeded_at": 1580832960,
  "result": {
    "id": "file_xs8vrJzC",
    "object": "file",
    "url": "https://files.stripe.com/v1/files/file_xs8vrJzC/contents",
    "created": 1580832960,
    "purpose": "report_run",
    "size": 53075,
    "type": "csv"
  }
}
```

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

#### curl

```bash
curl https://files.stripe.com/v1/files/file_xs8vrJzC/contents \
  -u <<YOUR_SECRET_KEY>>:
```

> #### CSV and API monetary formats differ
> 
> CSV reports express monetary amounts in major currency units, while Stripe API resources use integer amounts in minor currency units. For example, a CSV report represents 10 USD as `10.00`, while the API represents the same amount as `1000` (US cents).

### Report run notifications 

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

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

- Stripe sends a `reporting.report_run.succeeded` webhook if the run completes successfully.
- Stripe sends a `reporting.report_run.failed` webhook if the run fails. We recommend that integrations 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.

> Reports you run from the Dashboard don’t trigger the reporting webhook events.

## Automated reporting integration patterns 

Configure a webhook in live mode that explicitly receives `reporting.report_type.updated` events. Stripe doesn’t send these events in [sandboxes](https://docs.stripe.com/sandboxes.md). Webhooks that listen for all events don’t receive them.

1. Stripe sends a `reporting.report_type.updated` webhook as soon as a new day’s data is available for a given report type. The payload includes the updated `ReportType` object. You typically receive 20–30 webhooks each day, two for each report type. Different users are eligible for different reports.

2. After receiving the `reporting.report_type.updated` webhook for the desired report type and range of data availability, [create a report run](https://docs.stripe.com/api/reporting/report_run/create.md). The response contains a `ReportRun` object, initialized with `status=pending`.

3. When the run completes, Stripe sends a `reporting.report_run.succeeded` webhook. This webhook includes the nested property `result.url`. If the run fails, Stripe sends a `reporting.report_run.failed` event instead.

4. Access the file contents at `result.url`, using your API key.

Stripe monitors concurrent report runs for each account. To protect our infrastructure and maintain service quality for all users, we might throttle requests if too many reports are running simultaneously. If you encounter a rate limit error (HTTP 429), wait for some of your pending report runs to complete before requesting new ones.
