# Analytics

Programmatically access Stripe-defined metrics.

The Analytics API gives you synchronous, programmatic access to Stripe-defined metrics such as monthly recurring revenue (MRR), usage revenue, and so on. Use it within your own dashboards, analyze your data with the Stripe MCP, or integrate Stripe metrics into your internal tools.

It’s distinct from the [Reports API](https://docs.stripe.com/api/reporting.md), which provides asynchronous access to datasets, and the [Query Runs API](https://docs.stripe.com/stripe-data/sigma.md), which allows freeform SQL queries on raw Stripe data.

> The Analytics API is currently in private preview.

## Metric query

A metric query retrieves one or more metrics within the same metric namespace over a specified date range. You can group and filter results by the metric’s dimensions.

### The MetricQuery object

| Attribute                   | Type             | Description                                                                                                                 |
| --------------------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `object`                    | string           | String representing the object’s type. Value is `v2.data.analytics.metric_query`.                                           |
| `livemode`                  | boolean          | Whether this query contains live data or sandbox data.                                                                      |
| `refreshed_at`              | timestamp        | Timestamp representing the freshness of the underlying data.                                                                |
| `next_page_url`             | string or null   | URL to fetch the next page of results. Currently returns `null`.                                                            |
| `previous_page_url`         | string or null   | URL to fetch the previous page of results. Currently returns `null`.                                                        |
| `data`                      | array of objects | An array of result rows. Each element represents a row of timeseries data.                                                  |
| `data[].id`                 | string           | A unique identifier for this row.                                                                                           |
| `data[].timestamp`          | timestamp        | The start of this time bucket.                                                                                              |
| `data[].dimensions`         | object or null   | If `group_by` was specified, a hash of dimension key to dimension value (for example, `{"price": "price_HG4jxINMyHorkI"}`). |
| `data[].results`            | array of objects | The metric values for this row.                                                                                             |
| `data[].results[].metric`   | string           | The Gen6 ID of this metric (for example, `metric_61Sud3n5oAGVCWiSr5`).                                                      |
| `data[].results[].name`     | string           | The common name of this metric (for example, `mrr_minor_units`).                                                            |
| `data[].results[].value`    | integer          | The numeric value of this metric. Monetary values are in minor units (for example, cents).                                  |
| `data[].results[].currency` | string or null   | For monetary metrics, the three-letter ISO currency code. `null` for non-monetary metrics.                                  |

## Create a metric query 

Retrieves metric data for one or more metrics within the same metric namespace.

```
POST /v2/data/analytics/metric_query
```

### Parameters

| Parameter        | Required | Type             | Description                                                                                                                                                        |
| ---------------- | -------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `metrics`        | Yes      | array of objects | The metrics to query. Each object must include at least one of `id` or `name`. All metrics must belong to the same metric namespace.                               |
| `metrics[].id`   | No       | string           | The Gen6 ID for this metric (for example, `metric_61Sud3n5oAGVCWiSr5`).                                                                                            |
| `metrics[].name` | No       | string           | The common name for this metric. The common name is the concatenation of the metric namespace and the metric name separated by a `.` (for example, `revenue.mrr`). |
| `starts_at`      | Yes      | timestamp        | The beginning of the time range to query. Can’t be in the future.                                                                                                  |
| `ends_at`        | Yes      | timestamp        | The end of the time range to query. It must be after `starts_at`. Can’t be in the future.                                                                          |
| `interval`       | Yes      | enum             | The time interval to aggregate results by. One of `day`, `week`, `month`, or `year`.                                                                               |
| `currency`       | No       | string           | Three-letter ISO currency code for monetary metric results. Defaults to your account’s default currency.                                                           |
| `timezone`       | No       | string           | The IANA timezone for results (for example, `America/New_York`). Defaults to your account’s timezone. Max 64 characters.                                           |
| `filters`        | No       | object           | Dimension filters. Keys are dimension names, values are arrays of dimension values to include. Maximum 2 dimension keys, each with up to 10 values.                |
| `group_by`       | No       | array of strings | Dimensions to group results by. Maximum 1 dimension.                                                                                                               |
| `limit`          | No       | integer          | Maximum number of rows to return. Maximum value is `1000`.                                                                                                         |
| `page`           | No       | string           | A page token for pagination.                                                                                                                                       |

### Example request

#### curl

```shell
curl https://api.stripe.com/v2/data/analytics/metric_query \
  -X POST \
  -H "Authorization: Bearer sk_test_..." \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "metrics[0][id]=metric_61Sud3n5oAGVCWiSr5" \
  -d "starts_at=2026-03-01T00:00:00Z" \
  -d "ends_at=2026-03-03T00:00:00Z" \
  -d "interval=day" \
  -d "currency=usd" \
  -d "timezone=UTC" \
  -d "filters[price][0]=price_HG4jxINMyHorkI" \
  -d "filters[price][1]=price_HG4UtyJbuJIsVt" \
  -d "group_by[0]=price"
```

### Example response

```json
{
  "object": "v2.data.analytics.metric_query",
  "livemode": true,
  "refreshed_at": "2026-03-03T02:34:15Z",
  "next_page_url": null,
  "previous_page_url": null,
  "data": [
    {
      "id": "row_abc123",
      "results": [
        {
          "metric": "metric_61Sud3n5oAGVCWiSr5",
          "name": "mrr_minor_units",
          "currency": "usd",
          "value": 9000
        }
      ],
      "dimensions": {
        "price": "price_HG4jxINMyHorkI"
      },
      "timestamp": "2026-03-01T00:00:00Z"
    },
    {
      "id": "row_def456",
      "results": [
        {
          "metric": "metric_61Sud3n5oAGVCWiSr5",
          "name": "mrr_minor_units",
          "currency": "usd",
          "value": 12000
        }
      ],
      "dimensions": {
        "price": "price_HG4UtyJbuJIsVt"
      },
      "timestamp": "2026-03-01T00:00:00Z"
    },
    {
      "id": "row_ghi789",
      "results": [
        {
          "metric": "metric_61Sud3n5oAGVCWiSr5",
          "name": "mrr_minor_units",
          "currency": "usd",
          "value": 9150
        }
      ],
      "dimensions": {
        "price": "price_HG4jxINMyHorkI"
      },
      "timestamp": "2026-03-02T00:00:00Z"
    }
  ]
}
```

## Concepts 

### Metrics

A **metric** is a quantitative value built by aggregating raw Stripe data. Examples include monthly recurring revenue (MRR) and usage revenue.

Metrics often have *dimensions*—categorical attributes that a metric can be grouped or filtered by, such as `customer`, `product`, or `price`.

You can reference a metric by either its Gen6 ID (for example, `metric_61Sud3n5oAGVCWiSr5`) or its common name (for example, `mrr`). If you provide both `id` and `name`, they must refer to the same metric.

Monetary metric values are returned in minor units (for example, cents for USD). The `currency` field on the result object indicates the currency.

### Metric namespace

A *metric namespace* is a group of metrics that share the same dimensions. Metrics within the same namespace can be queried together in a single request. All metrics in a single `metric_query` request must belong to the same namespace.

For example, the `revenue` namespace might contain `mrr_minor_units`, `discounts_minor_units`, and `credits_minor_units`—all sharing dimensions such as `price`, `product`, and `customer`.

### Metric versioning

Metric versions are tied to [API versions](https://docs.stripe.com/upgrades.md). When a metric’s definition changes, it receives a new Gen6 ID and the common name points to the new version. Previous versions remain accessible using their Gen6 ID.

## Supported metrics 

See [Supported metrics](https://docs.stripe.com/stripe-data/analytics/supported-metrics.md) for the complete list of available metrics, their dimensions, and which dimensions support grouping and filtering.

## Errors 

| Error code                                       | HTTP status | Description                                                                                    |
| ------------------------------------------------ | ----------- | ---------------------------------------------------------------------------------------------- |
| `missing_resource`                               | 404         | The specified metric doesn’t exist.                                                            |
| `metric_inaccessible`                            | 403         | You don’t have the required permissions to view this metric.                                   |
| `missing_resource`                               | 400         | The metric is only accessible in live mode (when queried in a sandbox).                        |
| `metric_invalid_parameter_use`                   | 400         | Metrics in a single request must share the same namespace.                                     |
| `metric_invalid_parameter_use`                   | 400         | You must specify at least one of `id` and `name` for each metric.                              |
| `metric_invalid_parameter_use`                   | 400         | The `id` and `name` in a MetricIdentifier refer to different metrics.                          |
| `missing_resource`                               | 400         | Can’t group by or filter by a dimension that doesn’t exist on this metric.                     |
| `missing_resource`                               | 400         | A filter dimension value isn’t valid for the specified dimension.                              |
| `metric_invalid_parameter_use`                   | 400         | Can’t specify a currency for a metric with no monetary measures.                               |
| `metric_invalid_time_range`                      | 400         | Invalid time range: `starts_at` must be less than `ends_at`, and neither can be in the future. |
| `metric_invalid_time_range`                      | 400         | Time range exceeds the maximum allowed for the specified interval.                             |
| `metric_invalid_parameter_value`                 | 400         | An unsupported time zone was specified.                                                        |
| `metric_invalid_parameter_value`                 | 400         | Can’t `group_by` more than 1 dimension.                                                        |
| `metric_invalid_parameter_value`                 | 400         | Can’t filter on more than 10 values per dimension or more than 2 dimensions.                   |
| `metric_invalid_parameter_value`                 | 400         | `limit` can’t be greater than 1,000.                                                           |
| `metric_query_rate_limit_exceeded`               | 429         | Too many metric queries per second.                                                            |
| `metric_query_concurrency_limit_exceeded`        | 429         | Too many concurrent metric queries.                                                            |
| `metric_query_metric_rate_limit_exceeded`        | 429         | Too many queries per second for this specific metric.                                          |
| `metric_query_metric_concurrency_limit_exceeded` | 429         | Too many concurrent queries for this specific metric.                                          |

## Use cases 

### Build an internal MRR dashboard

Query daily MRR for specific prices, grouped by price, to use in an internal dashboard.

```javascript
const stripe = require('stripe')('sk_test_...');

const response = await stripe.v2.data.analytics.metricQuery.retrieve({
  metrics: [{ id: 'metric_61Sud3n5oAGVCWiSr5' }],
  starts_at: '2026-01-01T00:00:00Z',
  ends_at: '2026-01-31T00:00:00Z',
  interval: 'day',
  currency: 'usd',
  timezone: 'UTC',
  filters: {
    price: ['price_HG4jxINMyHorkI', 'price_HG4UtyJbuJIsVt'],
  },
  group_by: ['price'],
});

response.data.forEach((row) => {
  const date = new Date(row.timestamp).toISOString().split('T')[0];
  const priceId = row.dimensions.price;
  const mrrDollars = (row.results[0].value / 100).toFixed(2);
  const currency = row.results[0].currency.toUpperCase();
  console.log(`${date} | ${priceId} | ${currency} ${mrrDollars}`);
});
```

### Build a customer-facing usage dashboard

Query multiple metrics in the same namespace to show your end customers their usage breakdown, including spend, discounts, and credits.

```javascript
const stripe = require('stripe')('sk_test_...');

const response = await stripe.v2.data.analytics.metricQuery.retrieve({
  metrics: [
    { id: 'metric_61T01fRjnqbdNuZZ85' },  // discounts
    { id: 'metric_61T01fRjnJIJjie353' },  // credits
    { id: 'metric_61T01fR3j4kfJIbns6' },  // total spend
  ],
  starts_at: '2026-01-15T00:00:00Z',
  ends_at: '2026-01-30T00:00:00Z',
  interval: 'day',
  currency: 'usd',
  filters: {
    customer: ['cus_1234'],
    meter: ['mtr_1234'],
  },
});

response.data.forEach((row) => {
  const date = row.timestamp;
  row.results.forEach((result) => {
    const dollars = (result.value / 100).toFixed(2);
    console.log(`${date} | ${result.name}: $${dollars} ${result.currency}`);
  });
});
```

## Sandboxes 

The Analytics API supports querying metrics in sandboxes. Specify the live mode or sandbox Gen6 ID for the metric you want to query.
